我正在try 对我的Web API项目中的API的CRUD操作进行单元测试.我费了好大劲才弄明白如何删除.下面是我的服务;

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个错误.

推荐答案

您需要设置Test Double‘S 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,如上所示.

Csharp相关问答推荐

O(N)测试失败

什么是通过反射创建类的泛型接口方法的正确方法?

Unity 2D自顶向下弓旋转

如何使用新的Microsoft.IdentityModel.JsonWebToken创建JwtSecurityToken?

在命名管道上使用GRPC ASP.NET核心时如何配置命名管道权限

如何在ASP.NET Core8中启用REST应用程序的序列化?

CS1660无法将lambda表达式转换为类型INavigationBase,因为它不是委托类型

如何避免在.NET中将日志(log)写入相对路径

.Net MAUI,在将FlyoutPage添加到容器之前,必须设置添加构造函数导致Flyout和Detail"

这是否比决定是否使用ConfigureAWait(False)更好?

如何使用EPPlus C#在单个单元格中可视化显示多行文字

ASP.NET MVC数据批注验证组复选框

我想根据姓氏按字母顺序对包含150行徽章编号、姓氏、名字、地址等的文件进行排序.e

Visual Studio 17.8.0制表符自动完成问题--三缩进

RavenDb:为什么在字符串==空的情况下过滤会过滤得太多?

SharpZipLib在文件名前加上目录名,生成tar.gz

游戏对象走向不同的方向

我可以阻止类型上的Object.ToString()吗?

我什么时候不应该在Dispose中调用EgSuppressFinalize(This)?

是否在异步方法中避免Span<;T>;.ToArray()?