Model state validation in unit tests

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


As mentioned before, you need integration tests to validate the ModelState. So, with Asp.Net Core, I'm digging this question to add a simple solution for integrating tests with Asp.Net Core and validation of ModelState

Add the package Microsoft.AspNetCore.TestHost and you can submit requests this simple:

var server = new TestServer(new WebHostBuilder().UseStartup<Startup>());
var client = server.CreateClient();
var model = new { Name = String.Empty };
var content = new StringContent(JsonConvert.SerializeObject(model), Encoding.UTF8, "application/json");
var result = await client.PostAsync("/api/yourApiEndpoint", content);
result.StatusCode.Should().Be(HttpStatusCode.BadRequest);

You can find more about it here: http://asp.net-hacker.rocks/2017/09/27/testing-aspnetcore.html

Hope it helps.