我想说这在一定程度上是您真正想要通过单元测试验证的问题,这归结为您的单元测试理念。
我们所做的是,当在存储库协作者(未在测试中)上调用 GetFoo() 时,我们不一定要验证从类型 A(测试中)传递的 linq 到实体表达式参数是否使用特定的表达式树。对于单元测试,我们满足于验证 GetFoo() 方法是否调用了正确的签名。
在您的情况下,您似乎正在使用 Moq (?),在这种情况下会变成这样(注意语法混乱)
_mockRespository.Setup(r => r.GetFiltered(It.IsAny<Expression<Func<Entity, bool>>>())).Returns(new Order[0]).AtMostOnce();
对我们来说,这是有道理的,因为 a) 模拟方法参数表达式树比较验证确实很痛苦 b) 即使我们可以验证该参数,B 实际上如何解释参数值的不同组合可能会改变(如合约 A 的语义->B) 如果是这样的话,会使测试变得脆弱。
我们使用自动化故事测试来测试生产 A 和生产 B 之间的交互。我们认为这是测试这些场景的更好方法,因为它们通常类似于“根据表达式 X 过滤存储中的所有 A 并给我所有符合条件的对象”匹配'。对我们来说,这是有道理的,因为集成测试(通常一两个快乐的案例就足够了)。
如果这对您来说还不够,我会阅读 a)如何创建自定义 Moq 匹配器,尽管我不能肯定地说有一个简单的解决方案(很可能有)或 b)设置期望回调因此您可以捕获参数并在测试后对其进行检查。像这样的东西:
Expression<Func<Entity, bool>> actualExpression = null;
_mockRespository.Setup(r => r.GetFiltered(It.IsAny<Expression<Func<Entity, bool>>>())).Returns(new Order[0]).AtMostOnce().Callback((Expression<Func<Entity, bool>> expr => { actualExpression = expr});
// exercise production code
Assert.IsTrue(actualExpression ...... someithing clever here);
注意:以上所有代码都是在堆栈溢出编辑器中编写的。如果它不编译,不要追究我的责任,起订量文档涵盖了这一点