如何使用Xunit和Moq编写CustomerController的负测试用例?
负测试用例编写方案
负测试的核心是验证控制器在异常/非法场景下的行为是否符合预期,主要可以从以下几个方向入手:
1. 构造非法请求参数
针对请求中不符合业务规则的参数(比如必填字段缺失、参数值超出合法范围),验证控制器是否能正确识别并返回错误响应。
示例代码:
public async Task Test_CustomerDemand_InvalidRequest() { // Arrange: 构造非法请求(比如id为负数,ItemNumber为0) var invalidRequest = new GetRequest() { id = -1, // 非法ID abcnumber = 0, ItemNumber = 0 // 非法商品编号 }; var ctrl = new Controllers.CustomerController(_mockService.Object); // Act var result = await ctrl.CustomerDemand(invalidRequest); // Assert: 断言返回BadRequest var badRequestResult = result as BadRequestObjectResult; Assert.NotNull(badRequestResult); Assert.Equal(400, badRequestResult.StatusCode); }
2. 模拟服务层抛出异常
模拟服务调用失败的场景(比如数据库异常、业务规则校验失败抛出异常),验证控制器是否能捕获异常并返回合适的错误响应。
示例代码:
public async Task Test_CustomerDemand_ServiceThrowsException() { // Arrange: 模拟服务抛出异常 _mockService.Setup(x => x.GetDetails(It.IsAny<GetRequest>())) .ThrowsAsync(new ArgumentException("无效的请求参数")); var ctrl = new Controllers.CustomerController(_mockService.Object); // Act var result = await ctrl.CustomerDemand(_request); // Assert: 断言返回错误状态码(比如500或400,根据实际业务逻辑调整) var objectResult = result as ObjectResult; Assert.NotNull(objectResult); Assert.Equal(500, objectResult.StatusCode); // 或400,取决于控制器的异常处理逻辑 }
3. 模拟服务返回空/无效结果
如果业务中存在"请求合法但无对应数据"的场景,可以模拟服务返回null或空结果,验证控制器是否返回NotFound或其他对应响应。
示例代码:
public async Task Test_CustomerDemand_NoDataFound() { // Arrange: 模拟服务返回null _mockService.Setup(x => x.GetDetails(_request)) .Returns(Task.FromResult<GetResponse>(null)); var ctrl = new Controllers.CustomerController(_mockService.Object); // Act var result = await ctrl.CustomerDemand(_request); // Assert: 断言返回NotFound var notFoundResult = result as NotFoundResult; Assert.NotNull(notFoundResult); Assert.Equal(404, notFoundResult.StatusCode); }
补充说明
- 具体的响应类型(BadRequest/NotFound/InternalServerError)需要根据你的业务逻辑和控制器的实际实现来调整。
- 如果控制器使用了数据注解(比如
[Required]、[Range]),可以手动给ModelState添加错误,验证控制器是否能正确返回参数校验失败的响应。
内容的提问来源于stack exchange,提问作者Nitin bhatia
相关产品推荐
相关产品推荐

