I'm checking ModelState.IsValid
in my controller action method that creates an Employee like this:
[HttpPost] public virtual ActionResult Create(EmployeeForm employeeForm) { if (this.ModelState.IsValid) { IEmployee employee = this._uiFactoryInstance.Map(employeeForm); employee.Save(); } // Etc. }
I want to mock it in my unit test method using Moq Framework. I tried to mock it like this:
var modelState = new Mock<ModelStateDictionary>(); modelState.Setup(m => m.IsValid).Returns(true);
But this throws an exception in my unit test case. Can anyone help me out here?
Moq is a mocking framework built to facilitate the testing of components with dependencies. As shown earlier, dealing with dependencies could be cumbersome because it requires the creation of test doubles like fakes. Moq makes the creation of fakes redundant by using dynamically generated types.
Unit testing is a powerful way to ensure that your code works as intended. It's a great way to combat the common “works on my machine” problem. Using Moq, you can mock out dependencies and make sure that you are testing the code in isolation.
Moq supports mocking protected methods. Changing the methods to protected , instead of private , would allow you to mock their implementation.
IsValid is false now. That's because an error exists; ModelState. IsValid is false if any of the properties submitted have any error messages attached to them. What all of this means is that by setting up the validation in this manner, we allow MVC to just work the way it was designed.
You don't need to mock it. If you already have a controller you can add a model state error when initializing your test:
// arrange _controllerUnderTest.ModelState.AddModelError("key", "error message"); // act // Now call the controller action and it will // enter the (!ModelState.IsValid) condition var actual = _controllerUnderTest.Index();
The only issue I have with the solution above is that it doesn't actually test the model if I set attributes. I setup my controller this way.
private HomeController GenerateController(object model) { HomeController controller = new HomeController() { RoleService = new MockRoleService(), MembershipService = new MockMembershipService() }; MvcMockHelpers.SetFakeAuthenticatedControllerContext(controller); // bind errors modelstate to the controller var modelBinder = new ModelBindingContext() { ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => model, model.GetType()), ValueProvider = new NameValueCollectionValueProvider(new NameValueCollection(), CultureInfo.InvariantCulture) }; var binder = new DefaultModelBinder().BindModel(new ControllerContext(), modelBinder); controller.ModelState.Clear(); controller.ModelState.Merge(modelBinder.ModelState); return controller; }
The modelBinder object is the object that test the validity of the model. This way I can just set the values of the object and test it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With