0

I'm trying to write some unit tests using the Given-When-Then method. However, I don't seem to be able to mock a method inside the SUT that is called from the invoked method in the SUT. We're using the combinations of AutoFixture, NSubstiture and NUnit.

In this case I want to test the method CallingTheManager() in TheManager class. This method calls the CallTheBoss() method, but I'm unable to mock it.

Here I create another instance of ITheManager and mock the method, but this doesn't seem to do the trick. I also tried to mock the method on Sut, but this throws an exception.

Any idea how I can mock CallTheBoss()?

Note: The following code is pseudo-code derived from the actual implementation as a representation of what I try to achieve.

public abstract class GivenTheManagerWhenThenTest : GivenWhenTest
{
    protected TheManager Sut;

    protected ISomeManager SomeManager;
    protected IAnotherManager AnotherManager;
    protected ITheManager TheManager;

    protected override void Given()
    {
        SomeManager = Fixture.Freeze<ISomeManager>();
        AnotherManager = Fixture.Freeze<IAnotherManager>();
        TheManager = Fixture.Freeze<ITheManager>();

        Sut = new TheManager(SomeManager, AnotherManager);
    }
}
public class WhenCallingTheManager
{
    protected void Given()
    {
        SomeManager.SomeMethod(Arg.Any<int>()).Returns(new object());
        AnotherManager.AnotherMethod(Arg.Any<string>()).Returns(new string());
        TheManager.CallTheBoss(Arg.Any<string>()).Returns(true);
    }

    protected override void When()
    {
        Safe.AsyncExecute(async () => await Sut.CallingTheManager());
    }

    [Test]
    public void ThenCallsReceived()
    {
        SomeManager.Received(1).SomeMethod(Arg.Any<int>());
        AnotherManager.Received(1).AnotherMethod(Arg.Any<string>());
        TheManager.Received(1).CallTheBoss();
    }
}
public class TheManager : ITheManager
{
    private readonly ISomeManager _someManager;
    private readonly IAnotherManager _anotherManager;

    public TheManager(ISomeManager someManager, IAnotherManager anotherManager)
    {
        _someManager = someManager;
        _anotherManager = anotherManager;
    }

    public async void CallingTheManager()
    {
        await _someManager.SomeMethod(321);
        await _anotherManager.AnotherMethod("Calling all managers!");
        var calledTheBoss = await CallTheBoss("Pretty please.");
    }

    public Task<bool> CallTheBoss()
    {
        bool isBossHappy = false;
        // ...
        return isBossHappy;
    }
}
Niels R.
  • 7,260
  • 5
  • 32
  • 44
  • NSubstitute partial mock? https://nsubstitute.github.io/help/partial-subs/ – Serhii Shushliapin Oct 22 '19 at 10:28
  • I'm not sure on the AutoFixture part of the question, but to mock a class member it [needs to be `virtual`](https://nsubstitute.github.io/help/creating-a-substitute/#substituting-infrequently-and-carefully-for-classes). As @SerhiiShushliapin pointed out you can use partial subs to combine running real code and substitute code. – David Tchepak Oct 22 '19 at 22:45

0 Answers0