Mocking **class** with generic interface and methods

I have to mock a template method in a class. I am writing test for legacy code and have no possibility to change the code.

The interface looks like:

public interface ICommand<in I, out O>
    {
        O Execute(I input);
    }

The implementation:

public class GetCaseCommand : ICommand<string, Task<EsdhCaseResponseDto>>
{
     public Task<EsdhCaseResponseDto> Execute(string input)
     {
         return ExecuteInternal(input);
     }
}

I have to Mock that method from the class because (the Mock of) the class has to be a constructor parameter for another class, which will not accept the interface.

I have tried this test:

var mockGetCaseCommand = 
      new Mock<GetCaseCommand>(mockCommandGetLogger.Object, mockedEsdhService.Object);

mockGetCaseCommand.Setup(mGC => mGC.Execute(It.IsAny<string>()))
                .Returns(Task.FromResult<EsdhCaseResponseDto>(new EsdhCaseResponseDto()
                {
                    Title = "Title",
                    CaseId = "123456"
                }));

And get the exception:

System.NotSupportedException: 'Unsupported expression: mGC => mGC.Execute(It.IsAny()) Non-overridable members (here: GetCaseCommand.Execute) may not be used in setup / verification expressions.'

I have tried to find other ways to create the Setup. But the one above, is the only one which I can get compiled.

Any suggestions?

Upvotes: 0

Views: 517

Answers (1)

desertech
desertech

Reputation: 1029

Unit testing is a mean, not a goal.

If changing legacy code is out of question, you should accept the fact that your parent class is not purely testable and treat GetCaseCommand as internal behavior.

What might help you to keep a high degree of unit-testability is making what I call "second degree mocking", that is mock GetCaseCommand's dependencies (logger, service), which from your code snippets I infer they are represented as interfaces.

And if second degree mocking is also not possible - just do integration tests.

Upvotes: 2

Related Questions