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>()
)用于一个 out
或 ref
参数,你需要在调用之外定义它(这可能会有点容易出错:你需要确保按照它们将进入调用的顺序定义匹配器):
IAddAddressForm form = Substitute.For<IAddAddressForm>();
AddressItem item = Arg.Is<AddressItem>(y => y.Number == 14);
form
.When(x => x.SetItem(ref item))
.Do(x => );
var address = new AddressItem ;
form.SetItem(ref address);
ref
。你能解释一下吗? - David Tchepakref
的对象传递过去,则更新会失败(因为它不再识别该对象为查询的对象)。这可能不是 Linq to SQL 的“最佳实践”,但我是在训练单元测试,而不是 Linq。 - Vaccano