You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Moq和xUnit对Web API的Delete操作进行单元测试?

解决Web API Delete操作单元测试失败的问题

你的测试失败原因很明确:控制器的DeleteCompany方法会先调用GetCompanyById检查数据是否存在,但你只Mock了DeleteCompany方法,没对GetCompanyById做任何设置,Moq默认会返回null,导致控制器直接进入NotFound分支,返回404,而不是预期的204。

修正步骤:

  • Mock GetCompanyById方法,让它返回一个有效的Company实例,确保控制器能进入删除逻辑分支
  • 修正结果类型断言:控制器执行成功后返回的是NoContentResult,不是OkObjectResult,强转类型错误会直接抛出异常
  • 验证DeleteCompany是否被调用,确保删除逻辑确实被执行

修正后的测试代码:

[Theory]
[InlineData(1)]
public async Task CompanyController_DeleteCompany_ShouldReturnStatusCode204(int id)
{
    // 创建模拟的Company对象
    var mockCompany = new Company { Id = id, Name = "Test Company" };

    var mockRepo = new Mock<ICompanyRepository>();
    // Mock GetCompanyById方法,返回模拟对象
    mockRepo.Setup(repo => repo.GetCompanyById(id))
            .ReturnsAsync(mockCompany);
    // Mock DeleteCompany方法
    mockRepo.Setup(repo => repo.DeleteCompany(id))
            .Returns(Task.CompletedTask)
            .Verifiable();

    var sut = new CompanyController(mockRepo.Object);

    // 执行方法并转换为正确的结果类型
    var result = await sut.DeleteCompany(id);
    var noContentResult = result as NoContentResult;

    // 断言状态码为204
    noContentResult.StatusCode.Should().Be(204);
    // 验证DeleteCompany是否被调用过一次
    mockRepo.Verify(repo => repo.DeleteCompany(id), Times.Once);
}

额外说明:

  • 若要测试"当公司不存在时返回NotFound"的场景,可以单独写测试用例:MockGetCompanyById返回null,断言结果是NotFoundResult
  • 强转类型时尽量用as关键字,避免类型不匹配抛出异常,之后再判断是否为null,让测试更健壮

内容的提问来源于stack exchange,提问作者Aboliii

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 06:46:30