How to inject mocks into command handlers

I am writing unit tests for command handlers(existing code in my project). One of the command handlers invoke a query handler and uses the data that is returned by the query handler.

As part of my unit tests, I want to mock this call to query handler. How can i mock it and how can i inject mock into my fixture?

How can i (unit)test my command handler in isolation from the query handler?

Hi,

is the repository injected as a parameter to the command handler method, or as a (Spring) field?
In the first case, simply wire a mock/stub using FixtureConfiguration.registerInjectableResource().
In the latter case, you will need to register a custom AggregateFactory (one that injects the resource) with the fixture.

Cheers,

Allard

Hi Allard,

Appreciate your quick response!

The repository is injected as a Spring field. I was trying to do the first case solution for my case. Thanks for your guidance, will look into AggregateFactory.

Hi Allard,

Just want to be clear. I have a separate Command Handler class, not a Command Handler method in the AggregateRoot class. A snippet from my code is given below. Please take a look,

@Component
@Transactional
public class myCmdHandler implements IHandleCommand<MyCmd, UnitOfWork> {

@Autowired
private Repository repository;

@Autowired
private InterfaceMyQueryHandler myQueryHandler;

@Override
@CommandHandler
@Transactional
public void handle(MyCmd command, UnitOfWork tUnitOfWork) {

SomeData data = myQueryHandler.handle(new Query(command.getCaseId()));

if ( condition based on data )
{

MyAggregateRoot myAggregateRoot = MyAggregateRoot.createCaseVersion(command);
repository.add(myAggregateRoot );

} else {

}

}

I want to mock the data returned by myQueryHandler.

Is the solution still to use AggregateFactory?

I see in my source code, we don’t use AggregateFactory, instead we have static methods in the AR class to create AR and populate it with values from an event using Event Sourcing. I am not sure if i should introduce AggregateFactory in my code. Please advise. Thanks!

Just create a bean that returns a mocked InterfaceMyQueryHandler or do I miss something?

Maarten

Hi,

I suppose you want to use the command handler with the given-when-then test fixtures?
You’ll have to register your command handler with the fixture using fixture.registerCommandHandler()

That commandHandler will need to have all properties injected (so Spring field injection is not the best idea, consider constructor injection). To get an instance of the Repository, use fixture.getRepository().

Cheers,

Allard

Hi Allard,

Yes thats exactly what am doing.

I went ahead and implemented your solution. I changed spring field injection to constructor injection in my command handler and it is working fine. Thanks for the solution!

For this scenario, will spring field injection be supported by axon-test in near future?

Thanks!

The main advantage of dependency injection is that it improves unit testability. Field injection completely sets that advantage aside, and requires you to test your object using a DI container. There is a lot of material about field versus constructor (or setter) injection, and although field injection looks nice in code, it isn’t seen as the best practice.

Therefore, I am not sure if field injection will make it into Axon on the short term.

Cheers,

Allard

Hi Allard,

It completely makes sense to me. Thanks for your continuous support!!