Because the mvc project and test project are seperate, we need the test project to see the internal member in System.Web.Mvc project, so there is a attribute in the mvc project.

[assembly: InternalsVisibleTo("System.Web.Mvc.Test")]

The effort to make the project testable of the mvc project is very obvious. For example, to make DefaultControllerFactory testable, the class has a property setter, so that test project can inject mocking object.

DefaultControllerFactory factory = new DefaultControllerFactory();
MockBuildManager buildManagerMock = new MockBuildManager(new Assembly[] { });
ControllerTypeCache controllerTypeCache = new ControllerTypeCache();

factory.BuildManager = buildManagerMock;
factory.ControllerTypeCache = controllerTypeCache;

// Act
Type controllerType = factory.GetControllerType("sometype");

// Assert
Assert.IsNull(controllerType, "Shouldn't have found a controller type.");
Assert.AreEqual<int>(0, controllerTypeCache.Count, "Cache should be empty.");

//member of DefaultControllerFactory
internal IBuildManager BuildManager {
    get {
        if (_buildManager == null) {
            _buildManager = new BuildManagerWrapper();
        }
        return _buildManager;
    }
    set {
        _buildManager = value;
    }
}

internal ControllerBuilder ControllerBuilder {
    get {
        return _controllerBuilder ?? ControllerBuilder.Current;
    }
    set {
        _controllerBuilder = value;
    }
}

Another example is as follow. Even we need to increase performance of the by using staticControllerTypeCase, we still allow test project to inject an _instanceControllerTypeCase for testing.

//member of DefaultControllerFactory
internal ControllerTypeCache ControllerTypeCache {
    get {
        return _instanceControllerTypeCache ?? _staticControllerTypeCache;
    }
    set {
        _instanceControllerTypeCache = value;
    }
}

//member of ControllerContext
//RouteData can be mocked.
public virtual RouteData RouteData {
    get {
        if (_routeData == null) {
            _routeData = (_requestContext != null) ? _requestContext.RouteData : new RouteData();
        }
        return _routeData;
    }
    set {
        _routeData = value;
    }
}