【发布时间】:2017-10-26 09:56:46
【问题描述】:
我找不到可行的解决方案,即如何对 TransactionSynchronizationManager.registerSynchronization() 中发生的事情进行单元测试。我有这样的代码:
pubclic class MyService {
public void method() {
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter()
{
@Override
public void afterCommit()
{
myService.callSmth(params);
}
}
}
}
这里我调用method():
public class MyClass {
private MyService myService;
public void method2() {
myService.method();
}
}
在我的单元测试中,我需要验证 myService.callSmth。但似乎测试代码没有进入 afterCommit() 方法。 那是我的测试课:
@Configurable
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath*:test-applicationContext.xml" })
public class ServiceTest extends TestHelper
{
@Mock
MyService myService;
@InjectMocks
MyClass myClass;
@Test
public void allowWriteOffGlobal()
{
myClass.method();
veryfy(myService).method();
}
}
我简化了我的代码,请不要注意在这样的模拟和smth中是否有任何错误。在调试器中,我看到流程如何进入 TransactionSynchronizationManager.registerSynchronization 行并跳过 afterCommit() 方法。 P.s.:不确定我提供了足够的信息。如果需要额外的东西,请在评论中写下。谢谢。
【问题讨论】:
-
很难说没有更多细节(查看您的测试会有所帮助),但也许您的测试代码没有提交事务?针对事务数据源运行的测试通常会在测试完成时回滚,从而擦除任何测试数据并确保此类测试是自包含的。
-
我的测试中没有 @Transactional 注释。这不能保证提交会发生吗?
-
如果您更新您的问题以包含MCVE,您更有可能获得具体、相关、完整的答案。
-
所以你有一个 mock 并且你期望它的行为就像 spring 将创建它的真实对象一样。这显然行不通,您应该使用
@MockBean而不是@Mock和@InjectMocks的insteda 使用@Autowired,因为您需要实际配置的对象。最后,这几乎不是单元测试,而是集成测试。你真的需要事务同步,没有更简单的方法来解决这个问题吗?
标签: java spring unit-testing asynchronous junit