【问题标题】:Moq setup not returning expected object, mismatched invocationMoq 设置未返回预期对象,调用不匹配
【发布时间】:2013-12-19 19:59:52
【问题描述】:

我尝试使用 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 = "");

我的单元测试中的起订量设置:

_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() 但是我无法让它返回我需要的测试数据,任何帮助/指针将不胜感激

【问题讨论】:

  • 在我看来,您在 Setup() 中定义期望调用具有 4 个参数的 Find(),但 Verify() 告诉您它是使用单个参数调用的,但是调用 Find() 很麻烦,所以我可能读错了。
  • 我确实尝试使用带有单个参数的 .Find() 设置 Setup(),例如模拟 IQueryable Find(Expression> predicate);然而,这导致了参数计数不匹配异常,这导致我使用 Find() 的其他实现。感谢收看。
  • 正如 ledbutter 指出的那样,使用单个参数调用了 find 方法。我真的不明白为什么这解决了这个问题,但我将设置更改为在 Find 方法上使用单个参数,但也像这样重载 Returns 方法..._userRepository.Setup( x => x.Find(It.IsAny >>())) .Returns((Expression> 谓词) => existingAdmins.AsQueryable());这个链接帮助了我stackoverflow.com/questions/5196669/…

标签: c# linq unit-testing tdd moq


【解决方案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

【讨论】:

    猜你喜欢
    • 2022-01-14
    • 2020-08-13
    • 2016-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多