模拟方法仍然返回null

时间:2017-01-18 14:49:47

标签: c# .net moq

在我的新.Net Core项目中,我决定第一次使用Moq框架。根据教程设置所有方法后,我仍然得到例外:

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

或删除所有VerifyAll()调用后,从服务获取null。 知道怎么解决吗?

的依赖性:

  • “Microsoft.NETCore.App”:“1.1.0”,
  • “Moq”:“4.6.38-alpha”,
  • “xunit”:“2.2.0-beta5-build3474”,
  • “dotnet-test-xunit”:“2.2.0-preview2-build1029”,

字符:

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

通用存储库:

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

工作单位:

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

角色服务:

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

测试类:

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

1 个答案:

答案 0 :(得分:1)

这里的问题是,你比较两个表达式:

characterRepositoryMock.Setup中的第一个:x => x.Key == guid
GetCharacterByKey方法中的第二个方法:ch => ch.Key == characterKey

它们不相同,因为它们指向两个不同的Expression对象。 如果你真的想以这种方式测试它,你应该检查两个表达式是否得到相同的GUID值:

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

使用此检查方法:

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

并且,是的,我同意评论,VerifyAll应该在之后在Assert部分中被称为