Java TransactionSynchronizationManager内部的单元测试代码

Java TransactionSynchronizationManager内部的单元测试代码,java,spring,unit-testing,asynchronous,junit,Java,Spring,Unit Testing,Asynchronous,Junit,我找不到一个有效的解决方案,即如何对TransactionSynchronizationManager.registerSynchronization()中发生的事情进行单元测试。我有这样的代码: pubclic class MyService { public void method() { TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAd

我找不到一个有效的解决方案,即如何对TransactionSynchronizationManager.registerSynchronization()中发生的事情进行单元测试。我有这样的代码:

pubclic class MyService {
    public void method() {
        TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter()
                        {
                            @Override
                            public void afterCommit()
                            {
                                myService.callSmth(params);
                            }
                        }
    }
}
这里我调用方法():

在我的单元测试中,我需要验证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()方法。
附言:我不确定我提供了足够的信息。如果需要额外的smth,请写在评论中。谢谢。

尝试模拟
事务同步适配器
并在提交()后调用
afterCommit()

用@Transactional注释测试方法会导致测试在事务中运行,默认情况下,该事务将在测试完成后自动回滚。如果测试类用@Transactional注释,则该类层次结构中的每个测试方法都将在事务中运行。未使用@Transactional(在类或方法级别)注释的测试方法将不会在事务中运行。此外,使用@Transactional注释但传播类型设置为NOT_SUPPORTED的测试将不会在事务中运行

默认情况下,测试事务将在测试完成后自动回滚但是,事务提交和回滚行为可以通过@commit和@rollback注释在类级别和方法级别进行声明性配置


因此,我建议在测试方法中添加一个
@Commit
注释。(根据您描述的行为,我认为您正在使用Spring测试,否则此建议不适用)。

如果没有更多细节,很难说(查看您的测试会有所帮助),但您的测试代码可能不会提交事务?针对事务性数据源运行的测试通常会在测试完成时回滚,从而擦除所有测试数据并确保这些测试是自包含的。我的测试中没有@transactional注释。这并不能保证提交会发生?如果你更新你的问题以包含一个问题,你更有可能得到一个具体的、相关的、完整的答案。所以你有一个模拟,你希望它的行为像spring创建的真实对象一样。这显然不起作用,您应该使用
@MockBean
而不是
@Mock
,而不是
@InjectMocks
使用
@Autowired
,因为您需要实际配置的对象。最后,这不是一个单元测试,而是一个集成测试。您真的需要事务同步吗?有没有更简单的方法来解决这个问题?
@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();
    }
}