Web API 2 单元测试不考虑数据属性
DataAttributes not Respected in WebAPI2 Unit Tests
我正在尝试学习如何正确使用 WebApi2 项目的单元测试。在我过去的项目中,我经常使用 DataAnnotations 进行基本的模型验证。但是,它们在我的单元测试中似乎没有被正确触发。
在下面的示例中,实际的 API 控制器在收到真正的 HTTP 请求时表现正常。当我提交一个没有定义 ParrotTalk 的 JSON 对象时,它将 return 一个 BadRequest (400)。但是,TestMethod 似乎没有调用此规则。在不诉诸复杂方法的情况下,我该怎么做才能将其反映在我的单元测试中?这似乎应该可以正常工作 "out of the box",因为它们是内置的,并且是 MVC 中常用的功能。
这是我在 JSON 中上传的模型。
public class ParrotModel
{
[Required]
public string ParrotTalk { get; set; }
}
这是控制器中的实际方法。
[HttpPost]
[Route("another-endpoint")]
public IHttpActionResult CallParrotFromBody(ParrotModel Parrot)
{
if (!ModelState.IsValid)
{
return BadRequest();
}
return Ok(new TestModel { SomeString = "Bawwwwwk! " + Parrot.ParrotTalk });
}
这是我的测试方法。出于某种原因,当它运行时,ModelState.IsValid 是正确的...但在真实站点中 运行 不是!
[TestMethod]
public void CallParrotFromBody()
{
//good request
var controller = new RichController();
var result = controller.CallParrotFromBody(new ParrotModel { ParrotTalk = "Stuff" });
OkNegotiatedContentResult<TestModel> okResult = result as OkNegotiatedContentResult<TestModel>;
Assert.IsNotNull(okResult);
Assert.IsInstanceOfType(okResult.Content, typeof(TestModel));
Assert.AreEqual(okResult.Content.SomeString, "Bawwwwwk! " + "Stuff" );
//bad request---WHY DOESN'T THIS WORK????
var nullRequestController = new RichController();
var nullRequestResult = nullRequestController.CallParrotFromBody(new ParrotModel { });
BadRequestResult badResult = nullRequestResult as BadRequestResult;
Assert.IsNotNull(badResult);
}
在下图中,您可以清楚地看到代码的 IsValid 部分未被触发,因为未处理 [Required] 属性。只有在 MVC 应用程序外部(例如:从测试中)调用此方法时才会发生这种情况。
我认为您正在寻找的是单元测试与集成测试。
这里的问题是,当您进行单元测试时,您是在独立于其他组件和依赖项测试系统的一部分。在您的特定情况下,这意味着在测试控制器并将模型传递给它时,用于验证的应用程序部分未被初始化和使用。
为了测试当模型中出现错误时您的控制器是否正确运行,您实际上必须手动向控制器指示模型中存在错误,如下所示:
controller.ModelState.AddModelError("FieldName", "SomeError");
这样的事情会使模型无效,因此控制器中的 ModelState.IsValid
将 return false
.
如果您想检查您的验证引擎是否实际运行正确 - 例如如果我传递一个需要空字段的对象,控制器会 return http 状态 400 Bad Request
吗?
这实际上是集成测试,它涉及所有组件和依赖项,它们链接在一起,因此获得与您在服务器上实际拥有应用程序 运行 时类似的体验。
单元测试和集成测试之间存在很大差异 - 在单元测试中,您单独测试应用程序的特定部分,有时您必须模仿 运行ning 应用程序中由其他人处理的行为和情况自动初始化的组件。
在集成测试中,您实际测试了这些位如何在接近真实 运行ning 应用程序的环境中协同工作。
我正在尝试学习如何正确使用 WebApi2 项目的单元测试。在我过去的项目中,我经常使用 DataAnnotations 进行基本的模型验证。但是,它们在我的单元测试中似乎没有被正确触发。
在下面的示例中,实际的 API 控制器在收到真正的 HTTP 请求时表现正常。当我提交一个没有定义 ParrotTalk 的 JSON 对象时,它将 return 一个 BadRequest (400)。但是,TestMethod 似乎没有调用此规则。在不诉诸复杂方法的情况下,我该怎么做才能将其反映在我的单元测试中?这似乎应该可以正常工作 "out of the box",因为它们是内置的,并且是 MVC 中常用的功能。
这是我在 JSON 中上传的模型。
public class ParrotModel
{
[Required]
public string ParrotTalk { get; set; }
}
这是控制器中的实际方法。
[HttpPost]
[Route("another-endpoint")]
public IHttpActionResult CallParrotFromBody(ParrotModel Parrot)
{
if (!ModelState.IsValid)
{
return BadRequest();
}
return Ok(new TestModel { SomeString = "Bawwwwwk! " + Parrot.ParrotTalk });
}
这是我的测试方法。出于某种原因,当它运行时,ModelState.IsValid 是正确的...但在真实站点中 运行 不是!
[TestMethod]
public void CallParrotFromBody()
{
//good request
var controller = new RichController();
var result = controller.CallParrotFromBody(new ParrotModel { ParrotTalk = "Stuff" });
OkNegotiatedContentResult<TestModel> okResult = result as OkNegotiatedContentResult<TestModel>;
Assert.IsNotNull(okResult);
Assert.IsInstanceOfType(okResult.Content, typeof(TestModel));
Assert.AreEqual(okResult.Content.SomeString, "Bawwwwwk! " + "Stuff" );
//bad request---WHY DOESN'T THIS WORK????
var nullRequestController = new RichController();
var nullRequestResult = nullRequestController.CallParrotFromBody(new ParrotModel { });
BadRequestResult badResult = nullRequestResult as BadRequestResult;
Assert.IsNotNull(badResult);
}
在下图中,您可以清楚地看到代码的 IsValid 部分未被触发,因为未处理 [Required] 属性。只有在 MVC 应用程序外部(例如:从测试中)调用此方法时才会发生这种情况。
我认为您正在寻找的是单元测试与集成测试。
这里的问题是,当您进行单元测试时,您是在独立于其他组件和依赖项测试系统的一部分。在您的特定情况下,这意味着在测试控制器并将模型传递给它时,用于验证的应用程序部分未被初始化和使用。
为了测试当模型中出现错误时您的控制器是否正确运行,您实际上必须手动向控制器指示模型中存在错误,如下所示:
controller.ModelState.AddModelError("FieldName", "SomeError");
这样的事情会使模型无效,因此控制器中的 ModelState.IsValid
将 return false
.
如果您想检查您的验证引擎是否实际运行正确 - 例如如果我传递一个需要空字段的对象,控制器会 return http 状态 400 Bad Request
吗?
这实际上是集成测试,它涉及所有组件和依赖项,它们链接在一起,因此获得与您在服务器上实际拥有应用程序 运行 时类似的体验。
单元测试和集成测试之间存在很大差异 - 在单元测试中,您单独测试应用程序的特定部分,有时您必须模仿 运行ning 应用程序中由其他人处理的行为和情况自动初始化的组件。 在集成测试中,您实际测试了这些位如何在接近真实 运行ning 应用程序的环境中协同工作。