【问题标题】:Unit testing code inside TransactionSynchronizationManagerTransactionSynchronizationManager 中的单元测试代码
【发布时间】: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


【解决方案1】:

来自Spring Test documentation(强调我的):

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

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

所以我建议在您的测试方法中添加@Commit 注释。 (根据您描述的行为,我假设您正在使用 Spring Test,此建议不适用于其他情况)。

【讨论】:

    【解决方案2】:

    尝试模拟 TransactionSynchronizationAdapter 并调用 afterCommit()

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-16
      • 1970-01-01
      • 2018-12-15
      • 2015-08-19
      • 2011-10-25
      • 1970-01-01
      相关资源
      最近更新 更多