I have a database with Entity Framework, using a repository design pattern. There's a method in my repository which gets two inputs, an entity and an IQueryable<Entity>
collection. The method algorithm should return another entity from the collection, based on the entity input (for the sake of simplicity imagine a dating app where the userA gets userB as a recommendation, based on userA's preferences).
I have a test class library for testing the repository, using nUnit and MOQ. I setup the mock correctly to return a fake user list. and then I tested the method.
Here is the twist. The unit test fails, because the repository method returns null. However if I copy and paste the algorithm right into the unit test it returns the correct data. What's wrong? How is that possible? In the below code I commented the right and wrong stuff...
Repository method:
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;
}
At setup:
this.userRepo.Setup(x => x.GetAllIUsers()).Returns(testUsers);
this.userRepo.Setup(x => x.GetAll()).Returns(testUsers2.AsQueryable());
IUserRepository Repo = this.userRepo.Object;
At unit test:
[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...
}
Alright I finally figured out a solution to this. As I declared my mock as
private Mock<IUserRepository> userRepo = new Mock<IUserRepository>();
and then declared a repository as
IUserRepository Repo = userRepo.Object;
so when I called the
Repo.SearchForDate(IUser entity, IQueryable<USERS> users);
method, it was returning null all the time, because repo was just an interface without real implementation. So I decided to change the mock's type from IUserRepository
to UserRepository
and boom...
Suddenly it all started to working. Anyway, thanks guys for helping me out! :)