单元测试中的模型状态验证

ban*_*eas 27 c# unit-testing model-validation vs-unit-testing-framework asp.net-web-api

我正在为这样的控制器编写单元测试:

public HttpResponseMessage PostLogin(LoginModel model)
{
    if (!ModelState.IsValid)
        return new HttpResponseMessage(HttpStatusCode.BadRequest);
}
Run Code Online (Sandbox Code Playgroud)

该模型看起来像:

public class LoginModel
{
    [Required]
    public string Username { set; get; }
    [Required]
    public string Password { set; get; }
}
Run Code Online (Sandbox Code Playgroud)

然后我就像这样进行单元测试:

[TestMethod]
public void TestLogin_InvalidModel()
{
    AccountController controller = CreateAccountController();

    ...
    var response = controller.PostLogin(new LoginModel() {  });

    Assert.AreEqual(HttpStatusCode.BadRequest, response.StatusCode);

}
Run Code Online (Sandbox Code Playgroud)

实际上ModelState已经过验证......这对我来说很奇怪,因为这两个字段都是必需的......有人可以建议吗?

You*_*oui 27

模型状态有效的原因是当您新建控制器时会创建新的模型状态.Web API在这里没有为您执行参数绑定,因此它甚至没有机会添加模型状态错误.

如果您想将其作为单元测试,那么您应该自己添加模型状态错误并测试会发生什么.

如果您想测试模型状态在实际请求中是无效的,我建议您阅读此博客文章:

http://blogs.msdn.com/b/youssefm/archive/2013/01/28/writing-tests-for-an-asp-net-webapi-service.aspx

并尝试针对内存服务器进行测试.对于您的情况,一个小注意事项是您可能希望在请求上使用StringContent而不是ObjectContent,以确保Web API尝试反序列化并正确绑定正文.

  • 与Youssef +1.此外,您还可以查看请求管道的以下Web API海报.http://www.asp.net/posters/web-api/ASP.NET-Web-API-Poster-grayscale.pdf (2认同)

And*_*eas 20

TL; DR如果您不想阅读Youssef提供的整篇文章,并希望快速解决如何使ModelState.IsValid返回false.做这个.

[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);

}
Run Code Online (Sandbox Code Playgroud)

现在我可以想象CreateAccountController()看起来像这样最小 - >

return new AccountApiController()
{
    Request = new HttpRequestMessage(),
    Configuration = new HttpConfiguration()
};
Run Code Online (Sandbox Code Playgroud)

希望这给那些谷歌搜索的快速答案:)


Bru*_*lar 10

如前所述,您需要集成测试来验证ModelState.因此,使用Asp.Net Core,我正在挖掘这个问题,以便为Asp.Net Core集成测试和ModelState验证添加一个简单的解决方案

添加包Microsoft.AspNetCore.TestHost,您可以这么简单地提交请求:

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);
Run Code Online (Sandbox Code Playgroud)

你可以在这里找到更多相关信息:http: //asp.net-hacker.rocks/2017/09/27/testing-aspnetcore.html

希望能帮助到你.