0

I have the following class:

public class MyClass : IMyClass
{
    public string MyFunc(string name)
    {            
        if (string.IsNullOrWhiteSpace(name))
        {
            throw new Exception("Blank Name");
        }

        return name;
    }

    public double MyFuncWrapper(string name)
    {
        var value = MyFunc(name);

        return value;
    }

In trying to test it, I was under the impression that NSubstitute's ForPartsOf effectively subclassed my class and replaced the flagged methods; so I did this:

[Fact]
public void TestMyFuncWrapper()
{
    // Arrange
    var myClass = Substitute.ForPartsOf<MyClass>();            
    myClass.MyFunc(Arg.Any<string>()).Returns("Test");

    // Act
    var result = myClass.MyFuncWrapper("");

    // Assert
    Assert.Equal("Test", result);
}

However, I get the exception raised from, what I understood to be, my substituted method. Oddly, it appears that the following line:

myClass.MyFunc(Arg.Any<string>()).Returns("Test");

Is actually calling the concrete function immediately. Looking here, it appeared that a construct like this may solve the problem (although it does use the phrase "playing it safe" which sounds quite vague):

myClass.When(a => a.MyFunc(Arg.Any<string>())).DoNotCallBase();

However, calling this actually invokes MyFunc immediately in the same way. Clearly I'd misunderstood the ForPartsOf method; my question is: can I do what I'm attempting using NSubstitute, or do I need to resort to manually subclassing MyClass?

Paul Michaels
  • 16,185
  • 43
  • 146
  • 269

1 Answers1

2

This is by design for NSubstitute (and for most mocking frameworks).

The docs state:

For starters, NSubstitute can only work with virtual members of the class, so any non-virtual code in the class will actually execute!

Thus, you need to add virtual to the function declarations you plan to mock. Or (as per the docs):

If possible, stick to substituting interfaces.

mjwills
  • 23,389
  • 6
  • 40
  • 63