如何使用最小起订量和 xUnit 对删除操作进行单元测试?

How to Unit Test Delete operation using moq and xUnit?

提问人:Aboliii 提问时间:11/12/2023 最后编辑:Mark SeemannAboliii 更新时间:11/12/2023 访问量:41

问:

我正在尝试对 WEB API 项目中 API 的 CRUD 操作进行单元测试。我很难弄清楚如何为 DELETE 做到这一点。以下是我的服务;

public async Task DeleteCompany(int id)
{
    var query = "DELETE FROM Companies WHERE Id = @Id";
    using(var connection = _context.CreateConnection())
    {
        await connection.ExecuteAsync(query, new {id});
    }
}

这是控制器

[HttpDelete("{id}")]
public async Task<IActionResult> DeleteCompany(int id)
{
    var company = await _companyRepository.GetCompanyById(id);
    if (company == null)
    {
        return NotFound();
    }
    await _companyRepository.DeleteCompany(id);
    return NoContent();
}

下面是单元测试的代码

[Theory]
[InlineData(1)]
public async Task CompanyController_DeleteCompany_ShouldReturnStatusCode204(int id)
{
    var mockCompany = new Mock<ICompanyRepository>();
    mockCompany.Setup(service => service.DeleteCompany(id))
           .Returns(Task.CompletedTask)
           .Verifiable();

    var sut = new CompanyController(mockCompany.Object);

    var result = (OkObjectResult) await sut.DeleteCompany(id);

    result.StatusCode.Should().Be(204);
}

事实证明,它在调试后返回了我的模型(本例中为 Company)的 null 值。这就是为什么测试没有通过并且控制器出错的原因。NotFound

C# 单元测试 最小起订量 xunit fluent-assertions

评论


答:

2赞 Mark Seemann 11/12/2023 #1

您需要设置 Test Double 的方法,使其不会返回 null:GetCompanyById

[Theory]
[InlineData(1)]
public async Task CompanyController_DeleteCompany_ShouldReturnStatusCode204(int id)
{
    var mockCompany = new Mock<ICompanyRepository>();
    mockCompany.Setup(service => service.GetCompanyById(id))
        .ReturnsAsync(/*pass non-null value here*/);
    var sut = new CompanyController(mockCompany.Object);

    var result = (OkObjectResult) await sut.DeleteCompany(id);

    result.StatusCode.Should().Be(204);
    mockCompany.Verify(service => service.DeleteCompany(id);
}

另一方面,您不需要设置为可验证的操作,因为它无论如何都不会返回任何内容。命令的模拟,查询的存根。请改用,如上所示。DeleteCompanymockCompany.Verify