Kraver
Kraver

Reputation: 191

Mocked method still returns null

In my new .Net Core project I decided to use Moq framework for a first time. After I set up all method according to tutorial I still getting Exception:

"The following setups were not matched: IRepository`1 cr => cr.GetSingle(x => x.Key == 7028750f-044c-4862-999d-e21c4bfe7543) "

or after removing all VerifyAll() calls, a got null from serivice. Any idea how to solve it?

Dependences:

Character:

public class Character : IEntity
{
    ...
    public Guid Key { get; set; }
    ...
}

Generic repository:

public interface IRepository<TEntity> where TEntity : class, IEntity
{
    TEntity GetSingle(Expression<Func<TEntity, bool>> predicate);
    ...
}

Unit of work:

public interface IUnitOfWork
{        
    IRepository<TEntity> Repository<TEntity>() where TEntity : class, IEntity;       
    ...
}

Characters service:

class CharactersService : ICharactersService
{
    private readonly IUnitOfWork _unitOfWork;

    public CharactersService(IUnitOfWork unitOfWork)
    {
        _unitOfWork = unitOfWork;
    }

    public Character GetCharacterByKey(Guid characterKey)
    {
        var charactersRepository = _unitOfWork.Repository<Character>();
        var character = charactersRepository.GetSingle(ch => ch.Key == characterKey);
        return character;
    }
    ...
}

Test class:

public class CharactersServiceTest
{
    [Fact]
    public void GetCharacterByKey_CharacterExists_ReturnsCharacter()
    {
        //Arrange
        var guid = Guid.NewGuid();
        var characterFromDb = new Character { Key = guid };

        var characterRepositoryMock = new Mock<IRepository<Character>>();
        characterRepositoryMock.Setup(cr => cr.GetSingle(x => x.Key == guid)).Returns(characterFromDb);
        characterRepositoryMock.VerifyAll();

        var unitOfWorkMock = new Mock<IUnitOfWork>();
        unitOfWorkMock.Setup(uow => uow.Repository<Character>()).Returns(characterRepositoryMock.Object);
        unitOfWorkMock.VerifyAll();

        var charactersService = new CharactersService(unitOfWorkMock.Object);

        //Act
        var character = charactersService.GetCharacterByKey(guid);

        //Assert
        Assert.NotNull(character);
    }
}

Upvotes: 1

Views: 892

Answers (1)

Maksim Simkin
Maksim Simkin

Reputation: 9679

The problem here is, that you compare two expressions:

First in characterRepositoryMock.Setup : x => x.Key == guid
And the second one in GetCharacterByKey Method: ch => ch.Key == characterKey

They are not identical because they point to two different Expression objects. If you really want to test it such way, you should check, that both expressions get the same GUID value:

characterRepositoryMock.Setup(cr => 
  cr.GetSingle(It.Is<Expression<Func<Character, bool>>>(x =>check(x, guid)) ))
 .Returns(characterFromDb);

With this check method:

public bool check(Expression<Func<Character,bool>> x, Guid guid)
{
    var body = x.Body as BinaryExpression;  
    var g = (Guid) Expression.Lambda(body.Right).Compile().DynamicInvoke(); 
    return g == guid;
}

And, yes i agree with comments, VerifyAll should be called after all, in Assert part.

Upvotes: 1

Related Questions