如何在装饰有 [ApiController] 的控制器中进行单元测试模型验证?
How do I unit test model validation in controllers decorated with [ApiController]?
正如 to 中指出的那样,ASP.NET Core 2.1 的 ApiControllerAttribute 为我们提供的自动 ModelState 验证仅在实际请求运行时操作时有效,而不是通过使用无效参数调用它在单元测试中。
但是,我仍然想测试在提供错误模型时我的操作是否实际上 returns BadRequestResult。有什么办法吗?我知道我仍然可以手动检查 ModelState.IsValid 是否为 false,并自己返回 BadRequest(),但那样会破坏自动验证的意义。
毕竟我是手动检查ModelState.IsValid,还是有办法在单元测试中使用新的 ApiControllerAttribute 模型验证?
如果您想验证 api 在数据注释被破坏时是否返回了错误请求,那么您需要进行 api 集成测试。
一个不错的选择是 运行 通过使用 TestServer
的内存客户端进行集成测试
这是一个例子:
//arrange
var b = new WebHostBuilder()
.UseStartup<YourMainApplication.Startup>()
.UseEnvironment("development");
var server = new TestServer(b) { BaseAddress = new Uri(url) };
var client = server.CreateClient();
var json = JsonConvert.SerializeObject(yourInvalidModel);
var content = new StringContent(json, Encoding.UTF8, "application/json");
//act
var result = await client.PostAsync("api/yourController", content);
//assert
Assert.AreEqual(400, (int)result.StatusCode);
如果您只需要确保注释设置正确,您可以通过 TryValidateObject 方法手动触发验证
var obj = new YourClass();
var context = new ValidationContext(obj);
var results = new List<ValidationResult>();
var valid = Validator.TryValidateObject(obj, context, results, true);
正如
但是,我仍然想测试在提供错误模型时我的操作是否实际上 returns BadRequestResult。有什么办法吗?我知道我仍然可以手动检查 ModelState.IsValid 是否为 false,并自己返回 BadRequest(),但那样会破坏自动验证的意义。
毕竟我是手动检查ModelState.IsValid,还是有办法在单元测试中使用新的 ApiControllerAttribute 模型验证?
如果您想验证 api 在数据注释被破坏时是否返回了错误请求,那么您需要进行 api 集成测试。 一个不错的选择是 运行 通过使用 TestServer
的内存客户端进行集成测试这是一个例子:
//arrange
var b = new WebHostBuilder()
.UseStartup<YourMainApplication.Startup>()
.UseEnvironment("development");
var server = new TestServer(b) { BaseAddress = new Uri(url) };
var client = server.CreateClient();
var json = JsonConvert.SerializeObject(yourInvalidModel);
var content = new StringContent(json, Encoding.UTF8, "application/json");
//act
var result = await client.PostAsync("api/yourController", content);
//assert
Assert.AreEqual(400, (int)result.StatusCode);
如果您只需要确保注释设置正确,您可以通过 TryValidateObject 方法手动触发验证
var obj = new YourClass();
var context = new ValidationContext(obj);
var results = new List<ValidationResult>();
var valid = Validator.TryValidateObject(obj, context, results, true);