Reputation: 7084
I have some handler(in this example I just use controller):
@RestController
public class MessageController {
private final TaskExecutor taskExecutor;
private final Operation operation;
private final MessageLogService messageLogService;
public MessageController(TaskExecutor taskExecutor, Operation operation, MessageLogService messageLogService) {
this.taskExecutor = taskExecutor;
this.operation = operation;
this.messageLogService = messageLogService;
}
@PostMapping(value = "/process")
public String handleMessage(MessageRequest messageRequest){
MessageLog messageLog = messageLogService.createNewMessageLog();
taskExecutor.execute(() -> {
try {
operation.process(messageLog.getGuid(), messageRequest);
} catch (MessageLogDoesNotExistException e) {
throw new RuntimeException(e);
}
});
return "REQUEST_QUOTED";
}
}
MessageLog
in DB with status "NEW" and some default(and some data from the request in the real project) values and save.messageRequest
and MessageLog's guid
to the operation
in the executor and return sync response "REQUEST_QUOTED" immediately.
@Service
public class MessageOperation implements Operation {
private final MessageLogService messageLogService;
public MessageOperation(MessageLogService messageLogService) {
this.messageLogService = messageLogService;
}
@Transactional
@Override
public void process(String guid, MessageRequest messageRequest) throws MessageLogDoesNotExistException {
MessageLog messageLog = messageLogService.getOne(guid);
if (messageLog == null)
throw new MessageLogDoesNotExistException();
try {
Message message = createMessage(messageRequest);
messageLog.setStatus("SUCCESS");
messageLog.setMessage(message);
} catch (MessageCreationException e) {
messageLog.setStatus("FAIL");
messageLog.setErrorCode(e.getCode());
}
messageLogService.save(messageLog);
}
private Message createMessage(MessageRequest messageRequest) throws MessageCreationException {
//logic
return null;
}
}
Into operation
I create the message and bind it with messageLog. If I create and bind success - I set status 'SUCCESS' or 'FAIL' if not. And just save messageLog.
How can I create Unit test
for operation's
method process
? It is void.
1) I get a request from the client
2) delegate the request to the new thread for the async process
3) return sync response.
And I don't understand how can I create a unit test for public void process(String guid, MessageRequest messageRequest)
Upvotes: 0
Views: 81
Reputation: 381
In this case for MessageOperation
I recommend using Mockito
https://www.baeldung.com/mockito-annotations library for mocking the class attribute
@Mock
private final MessageLogService messageLogService;
Then in your unit test you use the verify()
method to check that expected behaviour has happened. (save is called correctly for example).
I would also mock the response of getOne
to fit your need
MessageLog messageLog = messageLogService.getOne(guid);
for example
MessageLog messageLog = new MessageLog();
when(messageLogService.getOne(eq("THE GUID YOU GIVE IN THE METHDO CALL"))).thenReturn(messageLog);
That way since you have the object reference to MessageLog
you can check for the status in the test code:
assertEquals("SUCCESS", messageLog.getStatus());
And use verify to check that the save method is called correctly:
verify(messageLogService).save(same(messageLog));
About the matchers I used https://www.baeldung.com/mockito-argument-matchers
Upvotes: 1