代码之家  ›  专栏  ›  技术社区  ›  Aboliii

如何使用moq和xUnit进行单元测试删除操作?

  •  1
  • Aboliii  · 技术社区  · 1 年前

    在我的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)的空值。这就是为什么测试没有通过 NotFound 控制器错误。

    1 回复  |  直到 1 年前
        1
  •  1
  •   Mark Seemann    1 年前

    您需要设置 Test Double GetCompanyById 方法,这样它就不会返回null:

    [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);
    }
    

    另一方面,您不需要设置 DeleteCompany 作为一个可验证的操作,因为它无论如何都不会返回任何内容。 Mocks for Commands, Stubs for Queries 使用 mockCompany.Verify 而是如上所示。