繁体   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