Search code examples
c#entity-frameworkunit-testingmoqreturn-value

Why the method doesn't work, however the same algorithm in another method works?


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

Solution

  • 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! :)