【问题标题】:Using Moq: mock object throwing 'TargetParameterCountException'使用最小起订量:模拟对象抛出“TargetParameterCountException”
【发布时间】:2009-10-26 16:58:46
【问题描述】:

我是 Moq 的新手,所以希望我只是在这里遗漏了一些东西。出于某种原因,我收到了 TargetParameterCountException。

你能看出我做错了吗?任何问题?请问。 :)

这是我的代码:

[Test]
  public void HasStudentTest_SaveToRepository_Then_HasStudentReturnsTrue()
  {
     var fakeStudents = new List<Student>();
     fakeStudents.Add(new Student("Jim"));

     mockRepository.Setup(r => r.FindAll<Student>(It.IsAny<Predicate<Student>>()))
                                .Returns(fakeStudents.AsQueryable<Student>)
                                .Verifiable();

     // in persistence.HasStudent(), repo.FindAll(predicate) is throwing 
     // 'TargetParameterCountException' ; not sure why
     persistence.HasStudent("Jim");
     mockRepository.VerifyAll();
  }

这是来自 Persistence 的 HasStudent 方法:

public bool HasStudent(string name)
  {
     // throwing the TargetParameterCountException
     var query = Repository.FindAll<Student>(s => s.Name == name); 

     if (query.Count() > 1)
        throw new InvalidOperationException("There should not be multiple Students with the same name.");

     return query.Count() == 1;
  }

【问题讨论】:

  • 如果将 It.IsAny 替换为 It.IsAny() 会发生什么?
  • @Kirschstein:那不会编译

标签: c# unit-testing mocking moq


【解决方案1】:

这个问题已经晚了,但为了 Google 员工......

我有一个非常相似的案例,我无法解释原因,但问题似乎在于在 .Returns() 内的通用列表上调用 AsQueryable。通过在模拟设置之前将 List 设置为 IQueryable 解决了问题。比如……

var fakeList = new List<foo>.AsQueryable();
...
mockRepository.Setup(r => r.FindAll<foo>(It.IsAny<foo>()))
                            .Returns(fakeList)
                            .Verifiable();

【讨论】:

  • 也有这个问题,你的帖子对我帮助很大。谢谢m8!
【解决方案2】:

FindAll 方法的签名是什么?您的存储库是否有重载 FindAll 方法?

如果是这样,那可能就是解释。您的 lamda 表达式可以编译成几种不同的类型,例如 Predicate&lt;Student&gt;Func&lt;Student, bool&gt;Expression&lt;Func&lt;Student, bool&gt;&gt;

我不确定我是否理解到底发生了什么,但 TargetParameterCountException 是属于 System.Reflection 命名空间的类型,因此这表明 Moq 以某种方式尝试使用错误数量的参数调用方法。最常见的原因是成员重载并且最终调用了错误的重载...

【讨论】:

  • 啊……我明白了。还有一个 FindAll() 重载。
  • 现在如何在不删除 FindAll() 的情况下解决这个问题?
  • 另外,签名是这样的:IQueryable FindAll(Predicate predicate) { }
  • 或:IQueryable FindAll() {}
  • 嗯...在这种情况下,您的设置看起来很明确,所以我不太明白发生了什么。两种方法都是虚拟的/抽象的吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-01-25
  • 1970-01-01
  • 2011-11-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多