簡體   English   中英

如何在NSubstitute 3.1中使用ref參數引發委托事件?

[英]How to raise a delegate event using a ref parameter in NSubstitute 3.1?

我正在使用第3方庫的C#項目中。 該庫使用ref參數定義了一個非常不尋常的委托事件:

event GetDataHandler OnGetData;
public delegate bool GetDataHandler(string name, ref byte[] data);

我正在嘗試通過NSubstitute(版本3.1)在單元測試中引發此事件,但是我無法使其正常工作。 我嘗試了這段代碼(基本上我可以想到的每個變體):

var theKey = "test";
byte[] theData = null;
_theObject.OnGetData += Raise.Event<GetDataHandler>(theKey, ref theData);

但這不能編譯。 編譯器說: 參數2可能不能與'ref'關鍵字一起傳遞

我知道NSubstitute 4.x的out / ref機制已經更改,但是我的公司尚未升級到較新版本。

有什么辦法可以使用NSubstitute 3.1來啟動和運行它? 非常感謝!

最好的問候,奧利弗

Raise.Event重載將參數作為params object[] 我們可以在此params數組中將byref字節數組作為標准值傳遞(這意味着我們對於傳遞的事件args不會獲得編譯時的安全性,但是如果我們弄錯了,測試會很快地將其提取出來) :)):

_theObject.OnGetData += Raise.Event<GetDataHandler>("name", theData);

這是一個可執行的示例:

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;
    }
}

在評論中提供更多信息后進行編輯。

我不認為NSubstitute支持檢查這種情況下返回的值。

在不完全知道您要測試的內容的情況下,我可以建議一些用於測試此類內容的一般方法。

第一種選擇是手工編寫一個可以完全控制的測試雙(本例中為ISomeType的實現)。 除非接口很大,否則我建議使用這種方法。

另一種選擇是分別測試代表和連線。 例如,給定此類:

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;
    }
}

我們可以獨立測試委托,然后測試我們已經將該委托連接起來了:

[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;
}

我認為在這種情況下,委托測試可能非常有用,但是連線測試可能並不好,因為它非常特定於特定的實現,而不是所需的行為/結果。 但是在這種情況下,很難觀察到特定的效果,因此這是一個潛在的答案。

第三,我們也許可以在所討論的庫中使用更具可測試性的包裝器。 或此測試可能完全處於錯誤的級別-警惕我們不擁有的模擬類型。 (我在這里已經寫了一些。)

如果您可以提供更多有關在這種情況下要測試的內容的信息,我們很樂意為您提供一個更合理的答案。 :)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM