Adley
Adley

Reputation: 541

Mock test returning null in NUnit .Net 5.0

I'm trying to make a simple mock tests in .Net 5.0 and NUnit. It's working for everything, but not for an specific method... and I can't find the solution.

First I have a logic 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);
    }
   
}

And in My Test Class, I Have

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

}

So my problem is that inside CreateGame_ShouldReturnNewGameWithLastDrawedCard() I create a mock that should return to me a Game object assing to newGame. But it ALWAYS return null. When debuggin, the line in CreateGame() is returning null

return await _gameRepository.Insert(newGame);

For others methods, like

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

var gameResult = await _gameBusiness.GetGame(5);

It works perfect. What I'm missing here?

Upvotes: 1

Views: 571

Answers (1)

Nkosi
Nkosi

Reputation: 247018

The issue is that the arguments do not match what was set up so it will return null by default.

Refactor to use an argument matcher and also to capture the model that was created within the member under test

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

Reference Moq Quickstart

Upvotes: 3

Related Questions