spa*_*pan 5 java unit-testing mockito spring-transactions
当我尝试测试使用手动事务的方法时,我的事务模板上出现空指针异常。当我在 Spring Boot 中运行应用程序时,它按预期工作。
@Autowired
TransactionTemplate template;
public CompletableFuture<MyResultEntity> addToA(BInput input) {
return CompletableFuture
.supplyAsync(
() -> template.execute(status -> {
A a = aRepository.findOne(input.getA());
List<B> addedBs = saveBs(input.getB(), a);
return new MyResultEntity(a, addedBs);
}), MyCustomExecutor());
}
Run Code Online (Sandbox Code Playgroud)
我尝试使用模拟模板并像这样注入它:
@Mock
private TransactionTemplate transactionTemplate;
@InjectMocks
private MyClass myClass;
Run Code Online (Sandbox Code Playgroud)
我还尝试用以下方式注释我的测试:
@RunWith(SpringJUnit4ClassRunner.class)
Run Code Online (Sandbox Code Playgroud)
调试此配置时,模板实际上已注入并且不再为空。但由于我有兴趣测试交易中的操作,我不想模拟它,所以我使用:
when(transactionTemplate.execute(Mockito.any())).thenCallRealMethod();
Run Code Online (Sandbox Code Playgroud)
这会引发一个新的空指针异常,因为事务模板尝试使用 TransactionManager 并且它仍然为空。
如何在交易模板内对我的方法调用进行单元测试?
我通常所做的不是调用真正的方法,而是只是模拟真实的行为。在模拟中调用真实方法将会失败,因为模拟不在 springs 注入上下文中进行管理。好吧,准确地说,您可以通过将它们添加到测试配置(普通 SpringMVC)或使用 @MockBean(spring boot)来使它们存在于注入上下文中。但它们仍然只是作为依赖项注入。但不会收到任何依赖项。对于单元测试来说,这通常是所需的行为。
所以只需做类似的事情:
when(_transactionTemplate.execute(any())).thenAnswer(invocation -> invocation.<TransactionCallback<Boolean>>getArgument(0).doInTransaction(_transactionStatus));
Run Code Online (Sandbox Code Playgroud)
_transactionStatus 本身可以是一个模拟,用于测试回调内状态的使用情况。
模拟就是模拟的用途:)
| 归档时间: |
|
| 查看次数: |
8550 次 |
| 最近记录: |