简体   繁体   English

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

[英]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? 实际上,ModelState已经过验证...对我来说这很奇怪,因为这两个字段都是必需的...有人可以建议吗?

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. Web API在这里没有为您做参数绑定,因此它甚至没有机会添加模型状态错误。

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 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. 针对您的情况的一个小注释是,您可能希望在请求上使用StringContent而不是ObjectContent,以确保Web API尝试正确地反序列化并绑定主体。

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. TL; DR如果您不想阅读Youssef提供的整篇文章,并希望快速找到如何使ModelState.IsValid返回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 -> 现在我可以想象CreateAccountController()看起来像这样->

return new AccountApiController()
{
    Request = new HttpRequestMessage(),
    Configuration = new HttpConfiguration()
};

Hope this gives a quick answer for those googling :) 希望这能为那些使用Google搜索的人提供快速解答:)

As mentioned before, you need integration tests to validate the ModelState. 如前所述,您需要集成测试来验证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 因此,对于Asp.Net Core,我正在研究这个问题,以添加一个简单的解决方案,以将测试与Asp.Net Core集成并验证ModelState

Add the package Microsoft.AspNetCore.TestHost and you can submit requests this simple: 添加软件包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);

You can find more about it here: http://asp.net-hacker.rocks/2017/09/27/testing-aspnetcore.html 您可以在这里找到更多关于它的信息: http : //asp.net-hacker.rocks/2017/09/27/testing-aspnetcore.html

Hope it helps. 希望能帮助到你。

I used the following to validate the model state in unit test Visual studio 2017, C#, NET 4.xx 我使用以下内容在单元测试Visual Studio 2017,C#,NET 4.xx中验证模型状态

   [TestMethod]
        public void TestYourValidationModel()
        {
            var configuration = new HttpConfiguration();
            configuration.Filters.Add(new ValidateModelAttribute());
            // Get the quote
            var controller = new YourController
            {
                Request = new HttpRequestMessage(),
                Configuration = configuration
            };
            var request = YourRequestObject;
            controller.Request.Content = new ObjectContent<YourRequestType>(
                request, new JsonMediaTypeFormatter(), "application/json");
            controller.Validate(request);
            Assert.IsTrue(controller.ModelState.IsValid, "This must be valid");
        }

The example is for a request in JSON format. 该示例适用于JSON格式的请求。 Substitute YourController for the name of your controller, and YourRequesType, for the object type of your request. 将YourController替换为控制器的名称,并将YourRequesType替换为请求的对象类型。

This give you the option to test your model for validation without go to the service. 这使您可以选择测试模型以进行验证,而无需使用服务。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM