簡體   English   中英

不調用受模擬的抽象類的受保護的虛方法

[英]Protected virtual method of a mocked abstract class is not called

我正在使用NSubstitute模擬一個抽象類,並期望調用其受保護的虛方法。

public abstract class A 
{
    protected virtual bool ProtectedMethod()
    {
        return true;
    }
    public bool PublicMethod()
    {
        return ProtectedMethod();
    }
}

public class ATest
{
    [Fact]
    public void Test()
    {
        var anA = Substitute.For<A>();

        var result = anA.PublicMethod();

        Assert.True(result);
    }
}

執行時此測試失敗。 事實上,即使課程不是抽象的,它也會失敗。 如果這是正常行為,我該怎么做才能確保調用ProtectedMethod?

PS。 如果該方法不是虛擬的,則按預期工作。

正如評論中指出的那樣, 小心取代課程 我建議安裝NSubstitute.Analyzers來在編譯時獲取類替換的問題。

此測試失敗的原因是因為您要替換A ,因此NSubstitute用替換的替換所有虛擬實現 (除非另有說明,否則通常返回default ,在這種情況下為false )。

您可以使用部分替換 ,它將默認維護現有實現(即ProtectedMethod將根據基本實現繼續返回true ):

[Fact]
public void TestUsingPartialSub() {
    var anA = Substitute.ForPartsOf<A>();

    var result = anA.PublicMethod();

    Assert.True(result);
}

“......我該怎么做才能確保調用ProtectedMethod?”

NSubstitute無法對受保護的方法斷言(它通過可公開訪問的API工作)。 如果可能,您可以重構代碼以使用策略模式來注入受保護的行為。 這將使代碼更加靈活(包括為測試注入不同行為的靈活性),代價是稍微復雜的設計。

public interface IProtectedMethod {
    bool ProtectedMethod();
}

public class AA {
    private readonly IProtectedMethod x;
    public AA(IProtectedMethod x) {
        this.x = x;
    }
    public bool PublicMethod() {
        return x.ProtectedMethod();
    }
}

public class AATest {
    [Fact]
    public void TestUsingStrategySub() {
        var x = Substitute.For<IProtectedMethod>();
        var anA = new AA(x);

        anA.PublicMethod();

        x.Received().ProtectedMethod();                
    }
}

(請原諒這個例子中的命名,我試圖讓它與原版保持相似,以便在各種邏輯位移動的地方更清楚。)

暫無
暫無

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

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