繁体   English   中英

C# 单元测试 mocking 服务忽略返回

[英]C# unit testing mocking service ignoring return

我正在编写一些单元测试来测试 controller。 在那个 controller 中有一个服务调用。 在我的测试中,我想模拟服务调用并显然指定所需的返回。

当代码运行时,它进入 controller 并且当它到达服务时,我可以清楚地看到它正在使用我的模拟。 但是,模拟的返回值始终是 null 而不是我指定的返回值(即expectedItem )。 任何想法?

针对控制器操作的单元测试

public class SearchIATeamControllerTests : IDisposable
{
    private readonly SearchIATeamController _sut;
    private IFixture _fixture;

    public SearchIATeamControllerTests()
    {
        _fixture = new Fixture().Customize(new AutoMoqCustomization());
        _sut = _fixture.Create<SearchIATeamController>();
    }


    [Fact]
    public async Task Get_team_name_with_ia_team_name_returns_ok()
    {
        // Arrange
        var expectedResultItem = _fixture.Create<SearchIATeamResponse>();

        var expectedItem = new List<SearchIATeamResponse>
        {
            expectedResultItem
        };

        var mockIATeamService = _fixture.Create<Mock<IIATeamSearchService>>();
        mockIATeamService.Setup(m => m.GetIATeamName(It.IsAny<string>())).ReturnsAsync(expectedItem);

        // Act
        var result = await _sut.Get("test").ConfigureAwait(false);
    }
} 

为简洁起见,名称已被缩写。

被测系统

public async Task<ActionResult<SearchIATeamResponse>> Get([FromQuery] string iATeamName)
{   
    if (iATeamName == null)
    {
        return BadRequest();
    }

    try
    {
        var result = await _searchIATeamService.GetIATeamName(iATeamName);

        if (!result.Any())
        {
            return NotFound();
        }

        return Ok(result);

     }
     catch (ArgumentException ex)
     {
         return BadRequest(ex.Message);
     }      
}

这里的一个关键点是您正在使用 AutoFixture 创建您的 Mock 和您的服务。 为了确保您的安装程序使用与注入服务的模拟实例相同的模拟实例,您可能希望在创建服务之前Freeze模拟实例。

public class SearchIATeamControllerTests : IDisposable
{
    private readonly SearchIATeamController _sut;
    private readonly Mock<IIATeamSearchService> _mockIATeamService;
    private IFixture _fixture;

    public SearchIATeamControllerTests()
    {
        _fixture = new Fixture().Customize(new AutoMoqCustomization());
        _mockIATeamService = _fixture.Freeze<Mock<IIATeamSearchService>>();
        _sut = _fixture.Create<SearchIATeamController>();
    }


    [Fact]
    public async Task Get_team_name_with_ia_team_name_returns_ok()
    {
        // Arrange
        var expectedResultItem = _fixture.Create<SearchIATeamResponse>();

        var expectedItem = new List<SearchIATeamResponse>
        {
            expectedResultItem
        };

        _mockIATeamService.Setup(m => m.GetIATeamName(It.IsAny<string>())).ReturnsAsync(expectedItem);

        // Act
        var result = await _sut.Get("test").ConfigureAwait(false);
    }
} 

请注意,我捕获了Freeze的结果,因此它更易于在测试方法中使用。 这是我喜欢的模式,但如果您不想让另一个私有字段挂起,理论上您可以在您的方法中继续使用_fixture.Create<>()

问题是由订单引起的 - controller 只能在模拟服务设置后声明,而不应在构造函数中声明。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM