Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Model state validation in unit tests

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?

like image 619
bandreas Avatar asked Jun 27 '13 15:06

bandreas


People also ask

What is model state validation?

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.

What is unit testing validation?

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.

What makes a unit test self validating?

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.


2 Answers

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.

like image 190
Youssef Moussaoui Avatar answered Sep 18 '22 12:09

Youssef Moussaoui


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 :)

like image 40
Andreas Avatar answered Sep 18 '22 12:09

Andreas