3

I am trying to mock a generic method and it doesn't work as expected.

I have this service definition

public interface ICommandHandlerFactory {
    ICommandHandler<T> GetHandler<T>() where T : ICommand;
}

and this Moq setup

var handler = new TestCommandHandler();
var handlerFactory = Mock.Of<ICommandHandlerFactory>(o => 
     o.GetHandler<TestCommand>() == handler);

If I call GetHandler method on the mock with the specific type e.g. GetHandler<TestCommand> everything is working as expected and it returns instance of the TestCommandHandler class.

But if the mock is injected to another generic class

public class CommandBus {
    private ICommandHandlerFactory _handlerFactory;

    public ICommandHandler GetHandler<T>(T command) where T : ICommand {
        return _handlerFactory.GetHandler<T>();
    }
}

the following piece of code return null

var command = new TestCommand();
return commandBus.GetHandler(command);

How should I setup Moq to return correct handler even in this case?

Lukas Kabrt
  • 5,441
  • 4
  • 43
  • 58
  • Maybe this question can also help: https://stackoverflow.com/questions/20072429/mocking-generic-methods-in-moq-without-specifying-t/58640455#58640455 – Mladen B. Oct 31 '19 at 09:48

2 Answers2

0

Have you tried something like this?

var handler = new TestCommandHandler();
Mock<ICommandHandlerFactory> handlerFactory = new Mock<ICommandHandlerFactory>();
handlerFactory.Setup(x => x.GetHandler<TestCommand>()).Returns(handler);

Mock<CommandBus> commandBus = new Mock<CommandBus>();
commandBus.Setup(x => x.GetHandler<TestCommand>(It.IsAny<TestCommand>())).Returns(handler);
dymanoid
  • 14,771
  • 4
  • 36
  • 64
0

The original code works, there was a problem in a helper method that initializes TestCommand class and that isn't included in the question.

Commands were casted to their base interface (ICommand) when initialized. The mock was setup to return handler for TestCommand type but is was called with ICommand type - that's why it returned null

Lukas Kabrt
  • 5,441
  • 4
  • 43
  • 58