Since I updated to ASP.NET MVC 3 Beta 1, I get a NullReferenceException
whenever I call TryUpdateModel()
during a unit test session.
The stack trace looks like this:
Execute System.NullReferenceException: Object reference not set to an instance of an object. at System.Web.Mvc.JsonValueProviderFactory.GetValueProvider(ControllerContext controllerContext) at System.Web.Mvc.ValueProviderFactoryCollect开发者_如何学Pythonion.<>c_DisplayClassc.b_7(ValueProviderFactory factory) at System.Linq.Enumerable.WhereSelectEnumerableIterator
2.MoveNext() at System.Linq.Enumerable.WhereSelectEnumerableIterator
2.MoveNext() at System.Collections.Generic.List1..ctor(IEnumerable
1 collection) at System.Linq.Enumerable.ToList[TSource](IEnumerable1 source) at System.Web.Mvc.ValueProviderFactoryCollection.GetValueProvider(ControllerContext controllerContext) at System.Web.Mvc.ControllerBase.get_ValueProvider() at Zeiterfassung.Controllers.ControllerBase
1.TryUpdateModelAndTrackChanges[TModel](TModel model, String prefix) in C:\Users\Adrian\Documents\Sites\Zeiterfassung\Zeiterfassung\Controllers\ControllerBase.cs:line 164 ... My own code from here on...
The same action method works fine when running on the web server, so my guess is that it is a problem with Dependency Injection in unit testing.
Is there something I need to setup for this to work? I'd rather not revert to the previous ASP.NET MVC version if possible.
You need to mock the ControllerContext. Personally I use MvcContrib.TestHelper which is based on Rhino Mocks to achieve this:
// arrange
var controller = new HomeController();
new TestControllerBuilder().InitializeController(controller);
// act
var actual = controller.Index();
but any mocking framework could do the job. You just need to make sure that in your unit test controller.ControllerContext
is not null.
If using Rhino Mocks alone (without MvcContrib.TestHelper), try the following:
controller = new HomeController(repository);
controller.ControllerContext = MockRepository.GenerateStub<ControllerContext>();
Personally, I actually create a Test Class level variable:
private HomeController controller;
Then for each test I re-initialize this variable:
[TestInitialize()]
public void MyTestInitialize()
{
controller = new HomeController();
controller.ControllerContext = MockRepository.GenerateStub<ControllerContext>();
}
精彩评论