[英]Protected virtual method of a mocked abstract class is not called
I am mocking an abstract class with NSubstitute and expect its protected virtual method to be 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);
}
}
This test fails when executed. 执行时此测试失败。 In fact, it fails even if the class is not abstract.
事实上,即使课程不是抽象的,它也会失败。 If this is normal behavior, what should I do to ensure the ProtectedMethod is called?
如果这是正常行为,我该怎么做才能确保调用ProtectedMethod?
PS. PS。 If the method is not virtual, it works as expected.
如果该方法不是虚拟的,则按预期工作。
As pointed out in the comments, be careful substituting for classes . 正如评论中指出的那样, 小心取代课程 。 I recommend installing the NSubstitute.Analyzers to pick up issues with class substitutes at compile time.
我建议安装NSubstitute.Analyzers来在编译时获取类替换的问题。
The reason this test is failing is because you are substituting for A
, so NSubstitute replaces all virtual implementations with substitute ones (which generally return default
unless otherwise stubbed out, in this case false
). 此测试失败的原因是因为您要替换
A
,因此NSubstitute用替换的替换所有虚拟实现 (除非另有说明,否则通常返回default
,在这种情况下为false
)。
You can use a partial substitute which will maintain the existing implementation by default (ie ProtectedMethod
will keep returning true
as per the base implementation): 您可以使用部分替换 ,它将默认维护现有实现(即
ProtectedMethod
将根据基本实现继续返回true
):
[Fact]
public void TestUsingPartialSub() {
var anA = Substitute.ForPartsOf<A>();
var result = anA.PublicMethod();
Assert.True(result);
}
"... what should I do to ensure the ProtectedMethod is called?"
“......我该怎么做才能确保调用ProtectedMethod?”
NSubstitute can not assert on protected methods (it works via the publicly accessible API). NSubstitute无法对受保护的方法断言(它通过可公开访问的API工作)。 If possible, you can refactor the code to use a strategy pattern to inject the protected behaviour.
如果可能,您可以重构代码以使用策略模式来注入受保护的行为。 This will make the code more flexible (including the flexibility to inject different behaviour for testing), at the cost of a slightly more complex design.
这将使代码更加灵活(包括为测试注入不同行为的灵活性),代价是稍微复杂的设计。
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();
}
}
(Please excuse the naming in this example, I've tried to keep it similar to the original to make it clearer where the various bits of logic have moved.) (请原谅这个例子中的命名,我试图让它与原版保持相似,以便在各种逻辑位移动的地方更清楚。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.