I am writing a unit test for a controller like this:
public HttpResponseMessage PostLogin(LoginModel model) { if (!ModelState.IsValid) return new HttpResponseMessage(HttpStatusCode.BadRequest); }
the model looks like:
public class LoginModel { [Required] public string Username { set; get; } [Required] public string Password { set; get; } }
Then I have unit test like this one:
[TestMethod] public void TestLogin_InvalidModel() { AccountController controller = CreateAccountController(); ... var response = controller.PostLogin(new LoginModel() { }); Assert.AreEqual(HttpStatusCode.BadRequest, response.StatusCode); }
Actually the ModelState is validated... which is weird for me as both fields are required... Could anybody advise?
Model state represents errors that come from two subsystems: model binding and model validation. Errors that originate from model binding are generally data conversion errors. For example, an "x" is entered in an integer field.
Unit Testing is a type of software testing where individual units or components of a software are tested. The purpose is to validate that each unit of the software code performs as expected. Unit Testing is done during the development (coding phase) of an application by the developers.
Self-validating: Each test will have a single boolean output of pass or fail. It should not be up to you to check whether the output of the method is correct each time the test is run.
The reason the model state is valid is that a new model state is created when you new up a controller. Web API isn't doing the parameter binding for you here, so it doesn't even have a chance to add model state errors.
If you want to keep this as a unit test, then you should add the model state errors yourself and test what happens.
If you want to test that the model state would be invalid on a real request, I recommend you read this blog post:
http://blogs.msdn.com/b/youssefm/archive/2013/01/28/writing-tests-for-an-asp-net-webapi-service.aspx
and try testing against an in-memory server. One minor note for your case would be that you may want to use a StringContent instead of an ObjectContent on the request to make sure that Web API tries to deserialize and bind the body properly.
TL;DR If you don't want to read the entire article provided by Youssef and want a quick solution to how to make ModelState.IsValid return false. Do this.
[TestMethod] public void TestLogin_InvalidModel() { AccountController controller = CreateAccountController(); // new code added --> controller.ModelState.AddModelError("fakeError", "fakeError"); // end of new code ... var response = controller.PostLogin(new LoginModel() { }); Assert.AreEqual(HttpStatusCode.BadRequest, response.StatusCode); }
Now I can imagine the CreateAccountController() looks something like this for minimum ->
return new AccountApiController() { Request = new HttpRequestMessage(), Configuration = new HttpConfiguration() };
Hope this gives a quick answer for those googling :)
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