ModelState.IsValid always true when testing Controller in Asp.Net MVC Web Api

|▌冷眼眸甩不掉的悲伤 提交于 2019-11-30 12:48:54

Your solution probably works, but a better way is using ApiController.Validate method.

public void MoviesController_Post_Without_Name()
{
    // Arrange
    var model = new MovieModel();
    model.Name = "";

    // Act
    controller.Validate(model);   //<---- use the built-in method
    var result = controller.Post(model);

    // Assert
    Assert.IsInstanceOfType(result, typeof(InvalidModelStateResult));
    Assert.AreEqual(6, controller.Get().Count());
}
André Baptista

Thanks to this site, I found out the solution:

private void SimulateValidation(object model)
{
    // mimic the behaviour of the model binder which is responsible for Validating the Model
    var validationContext = new ValidationContext(model, null, null);
    var validationResults = new List<ValidationResult>();
    Validator.TryValidateObject(model, validationContext, validationResults, true);
    foreach (var validationResult in validationResults)
    {
        this.controller.ModelState.AddModelError(validationResult.MemberNames.First(), validationResult.ErrorMessage);
    }
}

And including one line in the test method like this:

public void MoviesController_Post_Without_Name()
{
    // Arrange
    var model = new MovieModel();
    model.Name = "";

    // Act
    SimulateValidation(model);
    var result = controller.Post(model);

    // Assert
    Assert.IsInstanceOfType(result, typeof(InvalidModelStateResult));
    Assert.AreEqual(6, controller.Get().Count());
}

Hope that helps someone, it would have saved me some hours hunting the web.

This worked for me:

public MyResultData Post([FromBody] MyQueryData queryData)
{
    if (!this.Request.Properties.ContainsKey("MS_HttpConfiguration")) 
    {
        this.Request.Properties["MS_HttpConfiguration"] = new HttpConfiguration();
    }

    this.Validate(queryData);

    if (ModelState.IsValid)
    {
        DoSomething();
    }
}

Also check out this question: Validate fails in unit tests

On WebAPI 5.2.7:

[TestMethod]
public void MoviesController_Post_Without_Name()()
{
    // Arrange
    var model = new MovieModel();
    model.Name = "";

    controller.Request = new HttpRequestMessage();
    controller.Configuration = new HttpConfiguration();
    controller.Validate(model);

    // Act
    var result = controller.Post(model);

    // Assert
    ...

This article helped me: https://www.c-sharpcorner.com/article/unit-testing-controllers-in-web-api/

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!