Reputation: 45
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
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