模拟测试在 NUnit .Net 5.0 中返回 null

Mock test returning null in NUnit .Net 5.0

我正在尝试在 .Net 5.0 和 NUnit 中进行简单的模拟测试。它适用于所有情况,但不适用于特定方法...我找不到解决方案。

首先我有一个逻辑class:

public class GameBusiness : IGameBusiness
{
    private readonly IGameRepository _gameRepository;
    public GameBusiness(IGameRepository gameRepository)
    {
        _gameRepository = gameRepository;

    }
    public async Task<Game> CreateGame()
    {
        var drawCard = GenerateRandomCardValue();
        var newGame = new Game() { LastDrawedCard = drawCard };
        return await _gameRepository.Insert(newGame);
    }

    public async Task<Game> GetGame(int gameId)
    {
        return await _gameRepository.GetById(gameId);
    }

   
    private int GenerateRandomCardValue()
    {
        var random = new Random();
        return random.Next(1, 13);
    }
   
}

在我的测试中 Class,我有

private readonly Mock<IGameRepository> _gameRepository = new Mock<IGameRepository>();

    private readonly GameBusiness _gameBusiness;

    public GameRepositoryTest()
    {
        _gameBusiness = new GameBusiness(_gameRepository.Object);
    }

    [SetUp]
    public void Setup()
    {
    }

    [Test]
    public async Task GetGame_ShouldReturnGame_WhenGameExists()
    {
        var gameId = 5;
        var game = new Game()
        {
            Id = 5,
            LastDrawedCard = 3
        };

        _gameRepository.Setup(x => x.GetById(gameId)).ReturnsAsync(game);

        var gameResult = await _gameBusiness.GetGame(5);

        Assert.AreEqual(gameId, gameResult.Id);
    }

    [Test]
    public async Task CreateGame_ShouldReturnNewGameWithLastDrawedCard()
    {
        var newGame = new Game()
        {
            Id = 5,
            LastDrawedCard = 3
        };

        _gameRepository.Setup(x => x.Insert(new Game())).ReturnsAsync(newGame);

        var newGameResult = await _gameBusiness.CreateGame();

        Assert.IsTrue(newGame.LastDrawedCard > 0);
    }

}

所以我的问题是在 CreateGame_ShouldReturnNewGameWithLastDrawedCard() 中我创建了一个模拟,它应该 return 一个游戏对象分配给 newGame。但它总是 return 为空。 调试时,CreateGame() 中的行是 returning null

return await _gameRepository.Insert(newGame);

对于其他方法,例如

_gameRepository.Setup(x => x.GetById(gameId)).ReturnsAsync(game);

var gameResult = await _gameBusiness.GetGame(5);

效果很好。我在这里缺少什么?

问题是参数与设置不匹配,因此默认情况下 return 为空。

重构以使用参数匹配器并捕获在被测成员中创建的模型

[Test]
public async Task CreateGame_ShouldReturnNewGameWithLastDrawedCard() {
    //Arrange
    _gameRepository
        .Setup(x => x.Insert(It.IsAny<Game>())) //<-- uses a catch-all matcher
        .ReturnsAsync((Game arg) => arg); //<-- captures passed argument and returns it

    //Act
    var actual = await _gameBusiness.CreateGame();

    //Assert
    Assert.IsTrue(actual != null);
    Assert.IsTrue(actual.LastDrawedCard > 0);
}

引用Moq Quickstart