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.
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
).
You can use a partial substitute which will maintain the existing implementation by default (i.e. ProtectedMethod
will keep returning true
as per the base implementation):
[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?"
NSubstitute can not assert on protected methods (it works via the publicly accessible 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.)