[英]How to raise a delegate event using a ref parameter in NSubstitute 3.1?
I'm working on a C# project that uses a 3rd party library. 我正在使用第3方库的C#项目中。 This library defines a rather unusual delegate event using a ref parameter:
该库使用ref参数定义了一个非常不寻常的委托事件:
event GetDataHandler OnGetData;
public delegate bool GetDataHandler(string name, ref byte[] data);
I'm trying to raise this event in a unit test via NSubstitute (version 3.1) but I can't get it to work. 我正在尝试通过NSubstitute(版本3.1)在单元测试中引发此事件,但是我无法使其正常工作。 I tried this code (and basically every variation of it that I could think of):
我尝试了这段代码(基本上我可以想到的每个变体):
var theKey = "test";
byte[] theData = null;
_theObject.OnGetData += Raise.Event<GetDataHandler>(theKey, ref theData);
But this does not compile. 但这不能编译。 The compiler says: Argument 2 may not be passed with the 'ref' keyword .
编译器说: 参数2可能不能与'ref'关键字一起传递 。
I'm aware that the out/ref mechanism has changed with NSubstitute 4.x but my company has not upgraded to the newer version yet. 我知道NSubstitute 4.x的out / ref机制已经更改,但是我的公司尚未升级到较新版本。
Is there any way to get this up and running using NSubstitute 3.1? 有什么办法可以使用NSubstitute 3.1来启动和运行它? Thanks a lot!
非常感谢!
Best regards, Oliver 最好的问候,奥利弗
That Raise.Event
overload takes parameters as a params object[]
. Raise.Event
重载将参数作为params object[]
。 We can pass the byref byte array as a standard value in this params array (which means we don't get compile-time safety for the event args we're passing, but the test will pick this up pretty quickly if we get it wrong :) ): 我们可以在此params数组中将byref字节数组作为标准值传递(这意味着我们对于传递的事件args不会获得编译时的安全性,但是如果我们弄错了,测试会很快地将其提取出来) :)):
_theObject.OnGetData += Raise.Event<GetDataHandler>("name", theData);
Here's an executable example: 这是一个可执行的示例:
using NSubstitute;
using Xunit;
public delegate bool GetDataHandler(string name, ref byte[] data);
public interface ISomeType {
event GetDataHandler OnGetData;
}
public class SampleFixture {
string lastNameUsed = "";
byte[] lastBytesUsed = new byte[0];
[Fact]
public void SomeTest() {
var sub = Substitute.For<ISomeType>();
var data = new byte[] { 0x42 };
sub.OnGetData += Sub_OnGetData;
sub.OnGetData += Raise.Event<GetDataHandler>("name", data);
Assert.Equal("name", lastNameUsed);
Assert.Equal(data, lastBytesUsed);
}
private bool Sub_OnGetData(string name, ref byte[] data) {
lastNameUsed = name;
lastBytesUsed = data;
return true;
}
}
Edit after more info provided in comment. 在评论中提供更多信息后进行编辑。
I don't think NSubstitute supports inspecting the value that comes back in this case. 我不认为NSubstitute支持检查这种情况下返回的值。
Without knowing exactly what you're trying to test, I can suggest a couple of general approaches for testing this sort of thing. 在不完全知道您要测试的内容的情况下,我可以建议一些用于测试此类内容的一般方法。
First option is to hand code a test double (in this case an implementation of ISomeType
) that you have full control over. 第一种选择是手工编写一个可以完全控制的测试双(本例中为
ISomeType
的实现)。 Unless the interface is huge, I'd recommend this approach. 除非接口很大,否则我建议使用这种方法。
Another option is to test the delegate and the wire-up separately. 另一种选择是分别测试代表和连线。 For example, given this class:
例如,给定此类:
public class ClassUnderTest {
public ClassUnderTest(ISomeType dep) {
dep.OnGetData += Dep_OnGetData;
}
public static bool Dep_OnGetData(string name, ref byte[] data) {
data = System.Text.Encoding.UTF8.GetBytes(name);
return true;
}
}
We can test the delegate independently, and then test we've hooked up that delegate: 我们可以独立测试委托,然后测试我们已经将该委托连接起来了:
[Fact]
public void TestDelegate() {
byte[] data = new byte[0];
var result = ClassUnderTest.Dep_OnGetData("hi", ref data);
Assert.True(result);
Assert.Equal(new byte[] { 104, 105 }, data);
}
[Fact]
public void TestWireup() {
var sub = Substitute.For<ISomeType>();
var subject = new ClassUnderTest(sub);
sub.Received().OnGetData += ClassUnderTest.Dep_OnGetData;
}
I think the delegate test in this case is potentially very useful, but the wire-up test is probably not great because it is very specific to the particular implementation, rather than the behaviour/outcome required. 我认为在这种情况下,委托测试可能非常有用,但是连线测试可能并不好,因为它非常特定于特定的实现,而不是所需的行为/结果。 But in this case observing the particular effect is difficult, so it is a potential answer.
但是在这种情况下,很难观察到特定的效果,因此这是一个潜在的答案。
Thirdly, we may be able to use a more testable wrapper over the library in question. 第三,我们也许可以在所讨论的库中使用更具可测试性的包装器。 Or this test may be at the wrong level entirely -- be wary of mocking types we don't own.
或此测试可能完全处于错误的级别-警惕我们不拥有的模拟类型。 (I've written a bit about this here .)
(我在这里已经写了一些。)
If you can provide a little more info on what you're trying to test in this scenario I'm happy to try to come up with a more reasonable answer. 如果您可以提供更多有关在这种情况下要测试的内容的信息,我们很乐意为您提供一个更合理的答案。 :)
:)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.