我正在尝试编写用于Asp.Net Core Web API的ModelState验证的单元测试。
我读到,最好的方法是使用TryValidateModel
函数。但是,每次运行单元测试时,它都会引发NullReference异常。
我发现很多文章都建议使用controller.ModelState.AddModelError("","")
,但对此我并不感兴趣,因为我认为它超出了实际模型验证的实际目的。
[TestMethod]
public void TestMethod1()
{
var controller = new TestController();
controller.Post(new Model());
}
public class TestController : Controller
{
public IActionResult Post(Model model)
{
bool b = TryValidateModel(model)
return Ok();
}
}
TryValidateModel(model)
总是从TryValidateModel(model, prefix)
函数引发NullReference异常。
感谢任何帮助。
答案 0 :(得分:1)
这是配置/集成问题。
您可以在github上的issue in ASP.NET Core repo和another one中看到一些其他信息。 但是我可以告诉您最简单的修复方法(我使用过一次)
var objectValidator = new Mock<IObjectModelValidator>();
objectValidator.Setup(o => o.Validate(It.IsAny<ActionContext>(),
It.IsAny<ValidationStateDictionary>(),
It.IsAny<string>(),
It.IsAny<Object>()));
controller.ObjectValidator = objectValidator.Object;
答案 1 :(得分:1)
由于@Egorikas,我弄清楚了如何解决Null引用异常,我注意到它实际上并没有验证模型,并且始终返回true。
我发现我们只能在Validator
命名空间中使用System.ComponentModel.DataAnnotations
类。
[TestMethod]
public void TestMethod1()
{
var model = new Person();
var validationResultList = new List<ValidationResult>();
bool b1 = Validator.TryValidateObject(model, new ValidationContext(model), validationResultList);
}
如果打算使用ModelState验证,则可以直接从Test方法本身进行验证,而不必调用控制器。
希望这会有所帮助。
答案 2 :(得分:1)
基于Andrew Van Den Brink的答案,但实际上在ModelState中设置了验证错误。
private class ObjectValidator : IObjectModelValidator
{
public void Validate(ActionContext actionContext, ValidationStateDictionary validationState, string prefix, object model)
{
var context = new ValidationContext(model, serviceProvider: null, items: null);
var results = new List<ValidationResult>();
bool isValid = Validator.TryValidateObject(
model, context, results,
validateAllProperties: true
);
if (!isValid)
results.ForEach((r) =>
{
// Add validation errors to the ModelState
actionContext.ModelState.AddModelError("", r.ErrorMessage);
});
}
}
然后,只需在您的控制器中设置ObjectValidator:
controller.ObjectValidator = new ObjectValidator();
答案 3 :(得分:0)
public class ObjectValidator : IObjectModelValidator
{
private object parameter;
public ObjectValidator(object parameter)
{
this.parameter = parameter;
}
public void Validate(ActionContext actionContext, ValidationStateDictionary validationState, string prefix, object model)
{
var validationContext = new ValidationContext(parameter, null, null);
System.ComponentModel.DataAnnotations.Validator.ValidateObject(model, validationContext);
}
}
var model=new {}; // Model to test
Controller controller = new Controller(); //Controller to test
controller.ObjectValidator = new ObjectValidator(model);
这将引发异常