0

For testing purposes I want to run the real implementation of a class but see the functions that where called on it after its execution. If I understood that documentation correctly that is what the ForPartsOf is for. However after using it, it never returns any used calls (while I know they get triggered by breakpoints).

I created a small program to reflect my problem, at the end I would expect the console output to tell me both instances received 2 calls. but the 'real' one returns 0.

test interface:

    public interface ITestClass
    {
        string DoSomething();
    }

test class:

    public class TestClass : ITestClass
    {
        private readonly string mOutput;

        public TestClass(string output)
        {
            mOutput = output;
        }

        public string DoSomething()
        {
            return mOutput;
        }
    }

test program:

//using NSubstitute;
//using System;
//using System.Linq;

private const int cItterations = 2;

    public void Run()
    {
        ITestClass mock = Substitute.For<ITestClass>();
        mock.DoSomething().Returns("fake");

        ITestClass real = Substitute.ForPartsOf<TestClass>("real");

        RunCalls(mock); //fake, fake
        Console.WriteLine();
        RunCalls(real); //real, real
        Console.WriteLine();

        Console.WriteLine($"mock calls: {mock.ReceivedCalls().Count()}"); //mock calls: 2
        Console.WriteLine($"real calls: {real.ReceivedCalls().Count()}"); //real calls: 0 (expected 2?)
    }

    private void RunCalls(ITestClass implementation)
    {
        for (int i = 0; i < cItterations; i++)
        {
            Console.WriteLine(implementation.DoSomething());
        }
    }

I'm most likely doing something wrong but I can't seem to figure out what it is. Any help would be appreciated.

using: ms .net 4.7.2 with NSubstitute 4.0.0 (via nuget)

Nick Otten
  • 702
  • 7
  • 17

1 Answers1

2

NSubstitute cannot intercept non-virtual class members. (For an explanation as to why, please see the non-virtual members section of the How NSubstitute works documentation.)

Try it with DoSomething declared as a virtual member:

public class TestClass : ITestClass
{
    // ... other members elided ...

    public virtual string DoSomething()
    {
        return mOutput;
    }
}

Adding the NSubstitute.Analyzers package to your test projects will pick up cases where non-virtual members are used with NSubstitute.

David Tchepak
  • 9,826
  • 2
  • 56
  • 68