XUnit + Moq + FluentAssertions,检查 Task 上的 null 而不是正确的对象

XUnit + Moq + FluentAssertions, checking for null on Task instead of proper object

我是单元测试和最小起订量的新手。

使用 Postman 测试 DeleteItemAsync(),

    [HttpDelete("{id:length(24)}")]
    public async Task<IActionResult> DeleteItemAsync(string id)
    {
        var item = _ItemRepo.GetItemByIdAsync(id);
        if (item == null)
            return NotFound();
        await _itemRepo.DeleteItemAsync(id);
        return NoContent();
    }

当找不到项目时,我得到正确的结果,NotFound。

当 运行 我的单元测试失败时,因为在控制器中,它正在检查由 moq _repoStub 调用 GetItemByIdAsync(id) 返回的任务对象是否为空。

    [Fact]
    public async Task DeleteItemAsync_ItemDoesntExist_ReturnsNotFound()
    {
        // Arrange
        _repoStub
            .Setup(repo => repo.GetItemByIdAsync(It.IsAny<String>()))
            .ReturnsAsync((Item)null);
        _repoStub
            .SetupSequence(repo => repo.DeleteItemAsync(It.IsAny<String>()))
            .Returns(Task.FromResult<NotFoundResult>(null));

        var controller = new ItemController(_repoStub.Object, _mapperStub);

        // Act
        var actionResult = await controller.DeleteItemAsync(It.IsAny<String>());

        // Assert
        actionResult.Should().BeOfType<NotFoundResult>();
    }

GetItemByIdAsync待考科目

[HttpDelete("{id:length(24)}")]
public async Task<IActionResult> DeleteItemAsync(string id)
{
    var item =  await _ItemRepo.GetItemByIdAsync(id); //<--!!!
    if (item == null)
        return NotFound();
    await _itemRepo.DeleteItemAsync(id);
    return NoContent();
}

否则它会 return 一个 Task 而不是你的错误所显示的 null

此外,请注意 It.IsAny 只能用在期望表达式中,不能用作变量

[Fact]
public async Task DeleteItemAsync_ItemDoesntExist_ReturnsNotFound()
{
    // Arrange
    _repoStub
        .Setup(repo => repo.GetItemByIdAsync(It.IsAny<String>()))
        .ReturnsAsync((Item)null);
    _repoStub
        .SetupSequence(repo => repo.DeleteItemAsync(It.IsAny<String>()))
        .Returns(Task.FromResult<NotFoundResult>(null));

    var controller = new ItemController(_repoStub.Object, _mapperStub);

    // Act
    var actionResult = await controller.DeleteItemAsync(""); //<--It.IsAny<String>() removed

    // Assert
    actionResult.Should().BeOfType<NotFoundResult>();
}