【问题标题】:NSubstitute: Why does mock function call returns null when function parameter is byte[]/class?NSubstitute:当函数参数为byte[]/class时,为什么mock函数调用返回null?
【发布时间】:2020-07-15 17:07:25
【问题描述】:

我用 NSubstitute 创建了一个 Substitute

var mockService = Substitute.For<IService>(); 

仅当函数参数为 integer 时,我才能成功替换 IService 中的函数。在其他情况下,当我的代码调用 IService 的函数时,我会收到结果 null/0/byte[0]

MyResponse Request(byte[] request, MyAddress target); //null
int test(int t); //expected result
int SimpleRequest(byte[] request, MyAddress target); /0
MyResponse SimpleParam(int i); //expected result
byte[] testbyte(byte[] t); //byte[0]
byte[] testintbyte(int t); //expected result
int testbyteint(byte[] t); //0

当我在测试中证明这个函数时,它们会按预期返回值:

Assert.Equal(mockService.Request(request, target), MyResponse);//true

为什么我在 NSubstitute 中只能使用整数作为函数参数?

【问题讨论】:

标签: parameters null return nsubstitute


【解决方案1】:

似乎传递的byte[] 是一个不同的数组。它们可能具有相同的值,但引用不同。

var testBytes = new byte[] { 0x1, 0x2, 0x3 };

mockService.testbyteint(testBytes).Returns(42);

Assert.Equal(mockService.testbyteInt(testBytes), 42);

该测试应该通过,因为testBytes 值指向用于使用Returns 存根调用以及断言中使用的实际调用的相同引用。 Return for specific args 文档中还有更多示例。

对于我们没有所需确切参考的情况,我们可以使用argument matchers 来定义我们应该匹配哪些值:

var testBytes = new byte[] { 0x1, 0x2, 0x3 };

mockService.testbyteint(Arg.Is<byte[]>(bytes => bytes.SequenceEqual(new[] {0x1, 0x2, 0x3 })).Returns(42);

Assert.Equal(mockService.testbyteInt(testBytes), 42);

另一种选择是当我们不介意得到哪个参数时,我们可以使用ReturnsForAnyArgs

var testBytes = new byte[] { 0x1, 0x2, 0x3 };

mockService.testbyteint(null).ReturnsForAnyArgs(42);

Assert.Equal(mockService.testbyteInt(testBytes), 42);

希望这会有所帮助。

【讨论】:

  • 通常 SequenceEqual 适用于 byte[],但如果我按照您的建议将它放入 Arg.Is(...) 我会收到此错误:Error CS1929 'byte[]' does not contain a definition for 'SequenceEqual' and the best extension method overload 'Queryable.SequenceEqual&lt;byte&gt;(IQueryable&lt;byte&gt;, IEnumerable&lt;byte&gt;)' requires a receiver of type 'IQueryable&lt;byte&gt;'
  • 我的替换:mockRmqService.testbyteint( NSubstitute.Arg.Is&lt;byte[]&gt;( argbytes =&gt; argbytes.SequenceEqual&lt;byte&gt;(new[] { 90, 90, 90, 90, 90, 90, 90, 90, 90, 90 }) )).Returns(90);
  • 但它适用于我的真实代码mockRmqService.Request( NSubstitute.Arg.Is&lt;byte[]&gt;(argRequest =&gt; argRequest.SequenceEqual(ProgramListRequest)).Returns(clientResponse)!太好了!
  • @Alexandra 很高兴你成功了! SequenceEqual 可用性可能取决于您运行的 .NET 版本。您还可以根据需要实现自己的自定义谓词。
猜你喜欢
  • 2016-07-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-29
  • 2020-02-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多