我有一个带有实体框架的数据库,使用存储库设计模式。我的存储库中有一个方法,它获取两个输入,一个实体和一个
IQuerable<Entity>
集合。该方法算法应该根据实体输入从集合中返回另一个实体(为了简单起见,想象一个约会应用程序,其中 userA 根据 userA 的偏好将 userB 作为推荐)。
我有一个测试类库,用于使用 nUnit 和 MOQ 来测试存储库。我正确设置了模拟以返回假用户列表。然后我测试了该方法。
这是一个转折点。单元测试失败,因为存储库方法返回 null。但是,如果我将算法复制并粘贴到单元测试中,它将返回正确的数据。怎么了?这怎么可能?在下面的代码中,我评论了正确和错误的内容......
存储库方法:
public IUser SearchForDate(IUser entity, IQueryable<USERS> users)
{
var userPartner = users.Where(x => x.Interested == entity.Male)
.Where(x => x.MinAge < entity.Age)
.Where(x => x.MaxAge > entity.Age)
.Where(x => x.WantToDate == true).FirstOrDefault();
return userPartner;
}
设置时:
this.userRepo.Setup(x => x.GetAllIUsers()).Returns(testUsers);
this.userRepo.Setup(x => x.GetAll()).Returns(testUsers2.AsQueryable());
IUserRepository Repo = this.userRepo.Object;
单元测试时:
[TestCase("Andrew", "Angela")]
public void SearchForPartner_ReturnsTheCorrectPartner(string userName, string partnerName)
{
//Assert - Act
var users = Repo.GetAll();
var userNeedsPartner = users.Single(x => x.Nickname == userName); //this return the correct user - Andrew
var partner = Repo.SearchForDate(userNeedsPartner, Repo.GetAll()); //NOT GOOD, WHY????Even if I use users instead of Repo.GetAll() - this mothafucka returns null.
var partnerForUser = Repo.GetAll().Where(x => x.Interested == userNeedsPartner.Male)
.Where(x => x.MinAge < userNeedsPartner.Age)
.Where(x => x.MaxAge > userNeedsPartner.Age)
.Where(x => x.WantToDate == true).FirstOrDefault(); //GOOD, WHY??? - This returns the correct user - Angela
//Arrange
Assert.That(partner.Nickname, Is.EqualTo(partnerName)); //NULLReferenceException...
}
好吧,我终于找到了解决方案。当我宣布我的模拟为
private Mock<IUserRepository> userRepo = new Mock<IUserRepository>();
然后将存储库声明为
IUserRepository Repo = userRepo.Object;
所以当我打电话给
Repo.SearchForDate(IUser entity, IQueryable<USERS> users);
方法,它一直返回null,因为repo只是一个接口,没有真正的实现。所以我决定将模拟的类型从
IUserRepository
更改为 UserRepository
然后繁荣...
突然间,一切都开始起作用了。不管怎样,谢谢大家帮助我! :)