模拟方法仍然 returns null
Mocked method still returns null
在我的新 .Net Core 项目中,我决定第一次使用 Moq 框架。根据教程设置所有方法后,我仍然收到异常:
"以下设置不匹配:
IRepository`1 cr => cr.GetSingle(x => x.Key == 7028750f-044c-4862-999d-e21c4bfe7543) "
或在删除所有 VerifyAll() 调用后,从服务中获取空值。
知道如何解决吗?
依赖关系:
- "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;
}
...
}
测试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);
}
}
这里的问题是,您比较两个表达式:
在 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
应该在 之后被称为 ,在断言部分。
在我的新 .Net Core 项目中,我决定第一次使用 Moq 框架。根据教程设置所有方法后,我仍然收到异常:
"以下设置不匹配: IRepository`1 cr => cr.GetSingle(x => x.Key == 7028750f-044c-4862-999d-e21c4bfe7543) "
或在删除所有 VerifyAll() 调用后,从服务中获取空值。 知道如何解决吗?
依赖关系:
- "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;
}
...
}
测试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);
}
}
这里的问题是,您比较两个表达式:
在 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
应该在 之后被称为 ,在断言部分。