I am in the process of writing some unit tests for my controllers in RC1. Here is the controller’s public signature I’m testing:
[AcceptVerbs(HttpVerbs.Post)] public ActionResult AcceptColleague() {
The implementation inside the AcceptColleague uses the TryUpdateModel(colleague) method of populating the Colleague object from the form fields. However, I’m running into a ‘Object reference not set to an instance of an object’ error on the TryUpdateModel line while trying to unit test the method.
Here is my unit test code:
// definition HomeController controller = new HomeController(); IColleagueRepository fakeColleagueRepo = MockRepository.GenerateMock<IColleagueRepository>(); Colleague requestedColleauge = new Colleague(); EmployeeInfo currentUser = new EmployeeInfo(); HttpContextBase fakeHttpContext = MockRepository.GenerateMock<HttpContextBase>(); HttpRequestBase fakeHttpRequest = MockRepository.GenerateMock<HttpRequestBase>(); ControllerContext fakeContext = MockRepository.GenerateMock<ControllerContext>(fakeHttpContext, new RouteData(), controller); NameValueCollection fakeForm = new NameValueCollection(); // expectations fakeColleagueRepo.Expect(c => c.Read(1234)).Return(requestedColleauge); fakeColleagueRepo.Expect(c => c.Update(requestedColleauge)); fakeColleagueRepo.Expect(c => c.Add(new Colleague())).IgnoreArguments().Constraints(Is.NotNull()); fakeContext.Expect(cx => cx.HttpContext).Return(fakeHttpContext); fakeHttpContext.Expect(hcx => hcx.Request).Return(fakeHttpRequest); fakeHttpRequest.Expect(hr => hr.Form).Return(fakeForm); // setup controller.ColleagueRepository = fakeColleagueRepo; controller.ControllerContext = fakeContext; requestedColleauge.TargetEmployeeInfoId = 123456; requestedColleauge.GeneratedEmployeeInfoId = 654321; currentUser.EmployeeInfoId = 123456; fakeForm.Add('ColleagueId', '22222'); // action RedirectToRouteResult result = controller.AcceptColleague() as RedirectToRouteResult; // validation Assert.IsNotNull(result, 'AcceptColleague() did not return RedirectToRouteResult');
Am I missing something on the mocking or should I be using a different public signature like AcceptColleague(Colleague colleague) and then testing the ModelState.IsValid property?
If so, how don’t see a way I can mock the read only ModelState property off of the controller?
TryUpdateModel and ModelState both require zero mocks in RC 1. The only thing that you have to supply is a ValueProvider. For that, you can use FormCollection.ToValueProvider().
You’ll still need to mock your repository, but there is nothing that you need to mock in the framework for this functionality. Try this:
Note: No mocked HttpContext needed, unless your code requires it.