Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/asp.net-mvc-3/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net mvc 3 调用ModelState.IsValid的ASP MVC 3测试控制器始终返回true_Asp.net Mvc 3 - Fatal编程技术网

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

Asp.net mvc 3 调用ModelState.IsValid的ASP MVC 3测试控制器始终返回true,asp.net-mvc-3,Asp.net Mvc 3,我有一个ASP MVC 3应用程序,在我的模型中我实现了IValidatableObject 当我的控制器发布创建或编辑时,我显然只想保存有效的模型 我看到很多博客、帖子和答案都是这样写的 if(!ModelState.IsValid) { return View(); } 我的问题。为什么在控制器的单元测试中ModelState.IsValid始终为真 例如: [Test] public void InValidModelsAreNotAdded() { var inval

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

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

我看到很多博客、帖子和答案都是这样写的

if(!ModelState.IsValid)
{
      return View();
}
我的问题。为什么在控制器的单元测试中ModelState.IsValid始终为真

例如:

[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对于这个测试是正确的。就好像没有调用IValidatableObject.Validate一样。当我运行项目时,它似乎可以工作,但这不是一种测试应用程序的方法

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


思想?

这是真的,因为你没有说任何东西是假的

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


如果您试图测试验证,请直接进行。如果您试图测试控制器中的错误路径,则测试的arrange可以调用
\u controller.ModelState.AddModelError(//…
),而不是模拟模型绑定行为,您可以这样做:

public class YourController : Controller
{

    //some code

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

    //some code
}
对于我来说,使用“try-catch”块的可读性要高得多。但是,您仍然可以在该方法中使用“if”块


希望这有帮助!!

我不想用这个测试来测试验证。我想测试控制器在执行x之前是否已经验证了模型。控制器不验证模型。它们也不调用验证器。
ControllerActionInvoker
这样做。所有控制器可以做的就是测试状态。谢谢,小的范式转换,大的不同rence.:)控制器不应自行验证模型。