Moq设置不返回预期的对象,不匹配的调用

时间:2013-12-19 19:59:53

标签: c# linq unit-testing tdd moq

我有以下代码,我试图使用Moq模拟,特别是_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 
                });

Find()方法在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设置:

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

然而,当单元测试运行时,_userRepository.Find()在查看_userRepository.Verify()之后不返回预期的测试对象;我可以看到我的设置与执行调用不匹配,因此我没有得到我预期的对象返回。

执行调用:

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

我确实有单元测试传递和Moq _userRepository.Setup工作,直到我不得不更改_userRepository.Find()LINQ以防止以下异常:

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

我已经尝试更改_userRepository.Setup()但是我无法让它返回我需要的测试数据,任何帮助/指针都会非常感激

1 个答案:

答案 0 :(得分:1)

通过更改setup()以使用Find方法上的单个参数来修复此问题,但也重载了Returns方法,如此...

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

此链接有助于:

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