Rocy
Rocy

Reputation: 45

Moq setup not returning expected object, mismatched invocation

I have the following piece of code that I'm trying to mock out using Moq, specifically _userRepository.Find():

List<string> importEmails = ocrImportCentres.Select(c => c.CentreAdministratorEmail).Where(e => !string.IsNullOrWhiteSpace(e)).ToList();

 var existingUsersWithEmail =
            _userRepository.Find(
                x =>
                    importEmails.Contains(
                        x.PersonalDetailsHistory.OrderByDescending(h => h.DateCreated).FirstOrDefault().Email))
                .Select(o => new
                {
                    o.PersonalDetailsHistory.FirstOrDefault().Email,
                    (o as OCRInstitutionAdmin).UniqueId 
                });

The Find() methods are defined within IRepository:

IQueryable<T> Find(Expression<Func<T, bool>> predicate);
IQueryable<T> Find(Expression<Func<T, bool>> predicate = null, Func<IQueryable<T>, IOrderedQueryable<T>> orderBy = null, string includeProperties = "");

Moq setup within my unit test:

_userRepository.Setup(
            x =>
                x.Find(It.IsAny<Expression<Func<User, bool>>>(),
                    It.IsAny<Func<IQueryable<User>, IOrderedQueryable<User>>>(), It.IsAny<string>()))
            .Returns(existingAdmins.AsQueryable);

However when the unit test is ran _userRepository.Find() doesn't return the expected test object, after looking at the _userRepository.Verify(); I can see that my setup doesn't match the perform invocation and hence why I don't get my expected object returned.

Performed invocations:

IRepository`1. Find(x => value(OCRExamCreator.BusinessLogic.Services.OCRImportCentreManagementService+<>c__DisplayClasse).importEmails.Contains(x.PersonalDetailsHistory.OrderByDescending(h => h.DateCreated).FirstOrDefault().Email))

I did have the unit test passing and the Moq _userRepository.Setup working until I had to change the _userRepository.Find() LINQ to prevent the following exception:

{"Some part of your SQL statement is nested too deeply. Rewrite the query or break it up into smaller queries."}

I have tried changing _userRepository.Setup() however I can't get it to return the test data I need, any help/pointers would be much appreciated

Upvotes: 1

Views: 1356

Answers (1)

forsvarir
forsvarir

Reputation: 10859

Fixed the issue by changing the setup() to use a single parameter on the Find method but also overloaded the Returns method like so...

_userRepository.Setup( x => x.Find(It.IsAny<Expression<Func<User, bool>>>())) 
               .Returns((Expression<Func<User, bool>> predicate) => 
                                                             existingAdmins.AsQueryable());

This link helped:

Moq'ing methods where Expression<Func<T, bool>> are passed in as parameters

Upvotes: 1

Related Questions