NSubstitute支持ref参数吗?

5

我在我的接口中有以下方法签名:

void SetItem(ref AddressItem item);

我这样进行参数约束:

IAddAddressForm form = Substitute.For<IAddAddressForm>();
AddressItem item = null;
form.SetItem(Arg.Is(item));

但是由于引用的原因,它失败了。如果我将引用去掉,那么它就可以正常工作。但是我需要在这里传递引用。

你有什么想法吗?

附注:我的最终目标是在SetItem中抛出异常,如果传入的值为空,则会抛出异常。如果您能帮忙解决这个问题,那么您将获得额外的积分!


我真的很好奇你为什么需要在这里使用 ref。你能解释一下吗? - David Tchepak
嗯,我正在制作一个示例项目,以使用 NSubstitute 和 Moles 训练我的 IT 部门进行单元测试。作为其中的一部分,我想模拟 Linq-To-SQL。为了做到这一点,我需要对由 Linq-to-SQL 查询返回的对象进行一些更新。我发现如果不将带ref的对象传递过去,则更新会失败(因为它不再识别该对象为查询的对象)。这可能不是 Linq to SQL 的“最佳实践”,但我是在训练单元测试,而不是 Linq。 - Vaccano
你可以在这里查看导致我代码变成这样的问题/答案:https://dev59.com/B1DTa4cB1Zd3GeqPK6MZ#3770482 - Vaccano
1个回答

10

NSubstitute不直接支持匹配ref参数,但通常情况下它可以正常工作。

我假设你必须像你问题中所述一样使用ref,但是显然,如果你可以避免ref,你的API将更简单,无论你使用哪个框架测试它都是如此。

回答你的直接问题,你可以通过更新第二个代码示例来传递ref:

form.SetItem(ref item);

对于你的附注,请确保你不要试图将过多的行为推入你的替代品中。我发现每当我这样做时,它都是一个信号,说明我需要简化正在测试的类与其依赖之间的通信。(或者,如果我真的需要在伪对象中使用大量逻辑,我会手动编写一个而不是生成它;这通常会更加简单。)

有几种方法可以使此调用引发异常:

form.When(x => x.SetItem(ref item)).Do(x => { throw new ArgumentNullException(); });

只有在使用null引用调用时,才会抛出此异常。您还可以根据传递的参数选择性地添加此行为,尽管我建议不要这样做,因为这可能是您将太多内容推入替代品的迹象。

form.WhenForAnyArgs(x => x.SetItem(ref item))
    .Do(x => {
        if (x[0] == null)
            throw new ArgumentNullException();
    });

最后,如果你只想检查正在测试的类在IAddAddressForm抛出参数空异常时是否能够正确响应,那么我可能会这样做:

form
    .WhenForAnyArgs(x => x.SetItem(ref item))
    .Do(x => { throw new ArgumentNullException(); });

这样你就不需要真正关心参数是什么,你只需要确保你正在测试的代码对这种情况做出了适当的反应。

希望这可以帮到你。

SIDE NOTE:

如果你想要使用参数匹配器(比如 Arg.Any<AddressItem>())用于一个 outref 参数,你需要在调用之外定义它(这可能会有点容易出错:你需要确保按照它们将进入调用的顺序定义匹配器):

        IAddAddressForm form = Substitute.For<IAddAddressForm>();
        AddressItem item = Arg.Is<AddressItem>(y => y.Number == 14);
        form
            .When(x => x.SetItem(ref item))
            .Do(x => { throw new ArgumentNullException(); });
        var address = new AddressItem { Number = 14 };
        form.SetItem(ref address);

非常完整的答案!非常感谢。在我的替代代码中看起来可能有点繁琐,但这是因为我正在为我的同事进行培训,并且我的示例都有些牵强。 - Vaccano

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接