繁体   English   中英

NSubstitute模拟一个没有out / ref参数的void方法

[英]NSubstitute mock a void method without out/ref parameters

我试图模拟没有'out'或'ref'参数的void方法,但无法模拟它。 我想在模拟函数中修改参数

public interface IRandomNumberGenerator
{
    void NextBytes(byte[] buffer);
}

var randomImplementation = Substitute.For<IRandomNumberGenerator>();    
randomImplementation.When(x => x.NextBytes(Arg.Any<byte[]>())).Do(x =>
{
    x[0] = new byte[] {0x4d, 0x65, 0x64, 0x76};
});

但是当我运行此测试时出现错误:

NSubstitute.Exceptions.ArgumentIsNotOutOrRefException:'无法设置参数0(Byte []),因为它不是out或ref参数。

还有其他方法可以更改void方法中的参数吗?

x[0]引用传递给NextBytes的第一个参数,在您的情况下为buffer参数。 由于该参数不是refout ,因此在模拟成员中更改数组引用不会对调用代码产生任何影响。 因此,您有效地做到了:

class TheMoc : IRandomNumberGenerator
{
    public void NextBytes(byte[] bytes)
    {
        bytes = new byte[] {0x4d, 0x65, 0x64, 0x76};
    }
}

当然,这不会反映在调用代码中。 这就是NSubsitute给您例外的原因。

话虽如此,并不清楚为什么要这么做,因为调用代码将永远不会反映出接口对该数组的实际实现。

因此,当您的调用代码如下所示:

theGenerator.NextBytes(bytes);

该代码仍将引用“旧”数组,而不是“新”数组(您尝试嘲笑)。

所以,你需要提供帕拉姆作为refout以反映您的调用代码修改。

如果您知道数组将始终包含四个元素,则可以修改数组内容 ,而不是其引用

randomImplementation.When(x => x.NextBytes(Arg.Any<byte[]>())).Do(x =>
{
    x[0][0] = 0x4d;
    x[0][1] = 0x65;
    x[0][2] = 0x64;
    x[0][3] = 0x76;
});

因此,您不想匹配对NextBytes 任何调用,而只匹配那些提供四个字节的数组的调用,从而使Arg.Any<byte[]()> 有效地成为Arg.Is<byte[]>(x => x.Lengh == 4)

多亏了HimBromBeere,我才知道我做错了什么。

所以简单地我不能用新的填充字节数组传递,我需要替换数组中的每个项目

public interface IRandomNumberGenerator
{
    void NextBytes(byte[] buffer);
}

var randomImplementation = Substitute.For<IRandomNumberGenerator>();    
randomImplementation.When(x => x.NextBytes(Arg.Any<byte[]>())).Do(x =>
{
    var byteArray = x.Arg<byte[]>();
    byteArray [0] = 0x4d;
    byteArray [1] = 0x65;
    byteArray [2] = 0x64;
    byteArray [3] = 0x76;
});

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM