使用N取代的Func模拟结果
本文关键字:模拟 结果 Func 取代 使用 | 更新日期: 2023-09-27 18:16:49
我试图使用NSubstitute来模拟Substitute的返回值,但我无法让Substitute返回正确的值,因为方法签名使用的是Func。
我看到了这些问题,但无法用我的Func解决。
模仿动作<T>用N取代
用N-取代模拟表达
我试图模拟的接口是这样的(有点简单(:
public interface IOrgTreeRepository<out T> where T : IHierarchicalUnit
{
T FirstOrDefault(Func<T, bool> predicate);
}
我用N取代它,就像这样:
_orgTreeRepository = Substitute.For<IOrgTreeRepository<IOrganizationUnit>>();
然后我尝试更改返回值,如下所示:
_orgTreeRepository.FirstOrDefault(Arg.Is<Func<IOrganizationUnit, bool>>(x => x.Id== _itemsToUpdate[0].Id)).Returns(existingItems[0]);
但它只是返回一个代理对象,而不是我在existingItems中定义的对象。
然而,多亏了其他问题,我终于把它发挥了作用,但这对我没有帮助,因为我每次都需要一个特定的项目。
_orgTreeRepository.FirstOrDefault(Arg.Any<Func<IOrganizationUnit, bool>>()).Returns(existingItems[0]); // Semi-working
我想它是在把lambda表达式当作一种绝对引用,因此跳过它?有什么方法可以模拟返回值吗?
正如您正确猜测的那样,NSubstitute只是在这里使用引用相等,所以除非您有对同一谓词的引用(有时这是一个选项(,否则您必须匹配任何调用(Arg.Any
或.ReturnsForAnyArgs
(,或者使用近似的匹配形式来检查传入的函数。
近似匹配示例:
[Test]
public void Foo() {
var sample = new Record("abc");
var sub = Substitute.For<IOrgTreeRepository<Record>>();
sub.FirstOrDefault(Arg.Is<Func<Record,bool>>(f => f(sample))).Returns(sample);
Assert.AreSame(sample, sub.FirstOrDefault(x => x.Id.StartsWith ("a")));
Assert.AreSame(sample, sub.FirstOrDefault(x => x.Id == "abc"));
Assert.Null(sub.FirstOrDefault(x => x.Id == "def"));
}
在这里,每当Func<T,bool>
为sample
返回true
时,我们就将FirstOrDefault
截断为返回sample
(这是使用Arg.Is
的另一个重载,它接受一个表达式,而不是传入的参数值(。
这通过了对两个不同谓词的测试,因为sample
同时满足这两个谓词。它还传递了最后一个断言,因为它不会为检查不同id的函数返回sample
。我们不能保证在这种情况下使用了特定的谓词,但这可能已经足够了。否则,我们将在Func上使用参考质量。
希望这能有所帮助。