admin管理员组文章数量:1405731
I have a class where I am using transactional template and I wrote a Junit test for the same. However when I run the coverage,I do not have any line coverage on the code. The test is although green. This confuses me. Can somebody be kind enough to help me resolve this. Below is my production code.
@Test
void test() {
Optional<SomeParam> someParam = Optional.empty();
String TOPIC = "topic";
Token token = getToken();
Stream<Token> tokenStream = Stream.of(token);
TokenDto tokenDto = getDto();
when(specificDataMapper.fromToken(token)).thenReturn(tokenDto);
doAnswer(invocation -> {
TransactionCallbackWithoutResult callback = new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
Stream<Token> stream = tokenRepository.streamAll();
stream.forEach(t -> {
TokenDto payload = specificDataMapper.fromToken(t);
pubSubTemplate.publish(TOPIC, payload);
});
}
};
callback.doInTransaction(null);
return null;
}).when(transactionTemplate).executeWithoutResult(any());
doReturn(tokenStream).when(tokenRepository).streamAll();
publisherService.publishservice(someParam);
}
When I run in debug, the test is not entering the lamda function.
I have a class where I am using transactional template and I wrote a Junit test for the same. However when I run the coverage,I do not have any line coverage on the code. The test is although green. This confuses me. Can somebody be kind enough to help me resolve this. Below is my production code.
@Test
void test() {
Optional<SomeParam> someParam = Optional.empty();
String TOPIC = "topic";
Token token = getToken();
Stream<Token> tokenStream = Stream.of(token);
TokenDto tokenDto = getDto();
when(specificDataMapper.fromToken(token)).thenReturn(tokenDto);
doAnswer(invocation -> {
TransactionCallbackWithoutResult callback = new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
Stream<Token> stream = tokenRepository.streamAll();
stream.forEach(t -> {
TokenDto payload = specificDataMapper.fromToken(t);
pubSubTemplate.publish(TOPIC, payload);
});
}
};
callback.doInTransaction(null);
return null;
}).when(transactionTemplate).executeWithoutResult(any());
doReturn(tokenStream).when(tokenRepository).streamAll();
publisherService.publishservice(someParam);
}
When I run in debug, the test is not entering the lamda function.
Share edited Mar 10 at 8:24 Rohi asked Mar 7 at 11:31 RohiRohi 4272 gold badges5 silver badges18 bronze badges 3 |1 Answer
Reset to default 1The stubbed methods of your mock instances in your test never call your real method:
doAnswer(invocation -> {
TransactionCallbackWithoutResult callback = new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
Stream<Token> stream = tokenRepository.streamAll();
stream.forEach(t -> {
TokenDto payload = specificDataMapper.fromToken(t);
pubSubTemplate.publish(TOPIC, payload);
});
}
};
callback.doInTransaction(null);
return null;
}).when(transactionTemplate).executeWithoutResult(any());
It simply creates a new TransactionCallbackWithoutResult
instance and uses that to execute the code in the test (which seems to be copied verbatim from your production code's publishMessage
method?)
You probably want to call your real method. While this is possible to do in the doAnswer
block, it becomes convoluted and unmaintainable pretty quickly. Instead, I'd suggest to create a simple fake implementation of TransactionTemplate
to be used in your test. A trivial implementation simply calls the callback, without performing any transaction handling:
private static class FakeTransactionTemplate extends TransactionTemplate {
@Override
public <T> T execute(final TransactionTemplate<T> action) throws TransactionException {
return action.doInTransaction(new SimpleTransactionStatus());
}
}
Remove your Mockito mock and inject an instance of the fake transaction template into your service.
If you still want to use Mockito to re-implement the logic, you need to call the real template in your stub:
doAnswer(invocation -> {
final TransactionCallback<?> callback = invocation.getArgument(0)
callback.doInTransaction(new SimpleTransactionStatus()); // call the real callback!
return null;
}).when(transactionTemplate).executeWithoutResult(any());
But I'd advise against that. It gives you nothing over the fake implementation and only makes reasoning about your code harder.
本文标签: javaUnit testing using transaction templateStack Overflow
版权声明:本文标题:java - Unit testing using transaction template - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744932986a2633010.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
executeWithoutResult
method never calls the real code – why do you expect that? It creates a new transaction callback and then executes this one. It completely ignores the code inside yourpublish
method – knittl Commented Mar 9 at 15:46