调用ModelState.IsValid的ASP MVC 3测试控制器始终返回true

时间:2011-02-21 15:32:12

标签: asp.net-mvc-3

我有一个ASP MVC 3应用程序,在我的模型中,我实现了IValidatableObject。

当我的控制器发布创建或编辑时,我显然只想保存模型,如果它有效。

我看到很多博客,帖子和答案都说像

if(!ModelState.IsValid)
{
      return View();
}

我的问题。为什么ModelState.IsValid在Controller的单元测试中始终为true?

示例:

[Test]
public void InValidModelsAreNotAdded()
{
    var invalidModel = new MyModel() { SomeField = "some data", SomeOtherField = "" };

    var result = _controller.Submit(invalidModel);

    _repository.AssertWasNotCalled(r => r.Add(Arg.Is.Anything));

}

型号代码:


public class MyModel : IValidatableObject
{
    public string SomeField { get; set; }
    public string SomeOtherField { get; set; }

    public IEnumerable Validate(ValidationContext validationContext)
    {
        if(string.IsNullOrWhiteSpace(SomeOtherField))
        {
            yield return
                new ValidationResult("Oops invalid.", new[] {"SomeOtherField"});
        }
     }
}

AssertWasNotCalled总是无法通过此测试。

我完成了测试并注意到此测试的ModelState.IsValid为true。就好像没有调用IValidatableObject.Validate一样。它似乎在我运行项目时起作用,但这并不是测试驱动应用程序的方法。

另外,我意识到我可以在我的示例中使用[Required]属性,但我的真实代码对它的验证要复杂得多。

思想?

2 个答案:

答案 0 :(得分:23)

这是真的,因为你没有调用任何设置为假的东西。

这通常在绑定期间发生,但由于您只是在测试中直接传递模型,因此您完全跳过了该模型。

如果您正在尝试测试验证,请直接执行此操作。如果您尝试在控制器中测试错误路径,则测试的排列可以调用_controller.ModelState.AddModelError( //...

答案 1 :(得分:1)

好吧,试图模拟模型绑定行为,你可以这样做:

public class YourController : Controller
{

    //some code

    public ViewResult someAction(Model model)
    {
        try
        {
            ValidateModel(model);
        }
        catch
        {
            // deal with errors
        }
    }

    //some code
}
带有“try catch”块的

ValidateModel对我来说更具可读性。但您仍然可以使用方法TryValidateModel

的“if”块

希望有所帮助!!