gpt4 book ai didi

c# - 来自 Func 和 NSubstitute 的模拟结果

转载 作者:太空狗 更新时间:2023-10-29 21:16:58 28 4
gpt4 key购买 nike

我正在尝试使用 NSubstitute 来模拟 Substitute 的返回值,但我无法让替代品返回正确的值,因为方法签名使用的是 Func。

我已经看到这些问题,但无法使其与我的 Func 一起使用。

Mocking Action<T> with NSubstitute

Mocking out expression with NSubstitute

我尝试模拟的界面是这样的(有点简单):

public interface IOrgTreeRepository<out T> where T : IHierarchicalUnit
{
T FirstOrDefault(Func<T, bool> predicate);
}

我像这样用 NSubstitute 代替它:

_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"));
}

我们在这里 stub FirstOrDefault返回 sample每当 Func<T,bool>返回 true对于 sample (这是使用不同的 Arg.Is 重载,它接受一个表达式,而不是传入的参数值)。

这通过了两个不同谓词的测试,因为 sample满足他们两个。它还通过了最后一个断言,因为它不返回 sample对于检查不同 id 的函数。我们不能保证在这种情况下使用了特定的谓词,但它可能就足够了。否则,我们将在 Func 上停留在引用质量上。

希望这对您有所帮助。

关于c# - 来自 Func 和 NSubstitute 的模拟结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33017510/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com