ModelState.IsValid 在 Asp.Net MVC Web Api 中测试 Controller 时始终为真
ModelState.IsValid always true when testing Controller in Asp.Net MVC Web Api
我已尝试完成这项工作,并进行了多次 google/Whosebug 搜索,但一点运气都没有。
我有一个简单的模型:
public class MovieModel
{
public string Id { get; set; }
[Required]
[StringLength(100)]
public string Name { get; set; }
}
控制器中的一个方法:
// POST: api/Movies
public IHttpActionResult Post([FromBody]MovieModel movieModel)
{
if (ModelState.IsValid)
{
//Code
}
}
和一个测试方法(是一个集成测试,但同样会发生在单元测试中):
[TestMethod]
public void MoviesController_Post_Without_Name()
{
// Arrange
var model = new MovieModel();
model.Name = "";
// Act
var result = controller.Post(model);
// Assert
Assert.IsInstanceOfType(result, typeof(InvalidModelStateResult));
Assert.AreEqual(6, controller.Get().Count());
}
尽管模型显然无效,但它始终将 IsValid 属性 评估为真。
到目前为止我尝试了很多方法都没有成功。
感谢 this 网站,我找到了解决方案:
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);
}
}
并在测试方法中包含一行,如下所示:
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());
}
希望对某人有所帮助,它可以节省我上网的时间。
您的解决方案可能有效,但更好的方法是使用 ApiController.Validate 方法。
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());
}
这对我有用:
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();
}
}
另请查看此问题:
在 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
...
这篇文章对我有帮助:https://www.c-sharpcorner.com/article/unit-testing-controllers-in-web-api/
手动添加模型错误:
// Arrange
controller.ModelState.AddModelError("fakeError", "fakeMessage");
// Act
var result = controller.Post(model);
我已尝试完成这项工作,并进行了多次 google/Whosebug 搜索,但一点运气都没有。
我有一个简单的模型:
public class MovieModel
{
public string Id { get; set; }
[Required]
[StringLength(100)]
public string Name { get; set; }
}
控制器中的一个方法:
// POST: api/Movies
public IHttpActionResult Post([FromBody]MovieModel movieModel)
{
if (ModelState.IsValid)
{
//Code
}
}
和一个测试方法(是一个集成测试,但同样会发生在单元测试中):
[TestMethod]
public void MoviesController_Post_Without_Name()
{
// Arrange
var model = new MovieModel();
model.Name = "";
// Act
var result = controller.Post(model);
// Assert
Assert.IsInstanceOfType(result, typeof(InvalidModelStateResult));
Assert.AreEqual(6, controller.Get().Count());
}
尽管模型显然无效,但它始终将 IsValid 属性 评估为真。
到目前为止我尝试了很多方法都没有成功。
感谢 this 网站,我找到了解决方案:
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);
}
}
并在测试方法中包含一行,如下所示:
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());
}
希望对某人有所帮助,它可以节省我上网的时间。
您的解决方案可能有效,但更好的方法是使用 ApiController.Validate 方法。
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());
}
这对我有用:
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();
}
}
另请查看此问题:
在 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
...
这篇文章对我有帮助:https://www.c-sharpcorner.com/article/unit-testing-controllers-in-web-api/
手动添加模型错误:
// Arrange
controller.ModelState.AddModelError("fakeError", "fakeMessage");
// Act
var result = controller.Post(model);