java - JUnit 测试 Spring @Async void 服务方法

标签 java spring junit spring-async

我有一个 Spring 服务:

@Service
@Transactional
public class SomeService {

    @Async
    public void asyncMethod(Foo foo) {
        // processing takes significant time
    }
}

我对此有一个集成测试 SomeService :

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
@WebAppConfiguration
@IntegrationTest
@Transactional
public class SomeServiceIntTest {

    @Inject
    private SomeService someService;

        @Test
        public void testAsyncMethod() {

            Foo testData = prepareTestData();

            someService.asyncMethod(testData);

            verifyResults();
        }

        // verifyResult() with assertions, etc.
}

问题来了:

  • 作为 SomeService.asyncMethod(..)注释为 @Async
  • 作为 SpringJUnit4ClassRunner遵守 @Async语义

testAsyncMethod线程将 fork 调用 someService.asyncMethod(testData)进入自己的工作线程,然后直接继续执行verifyResults() ,可能在前一个工作线程完成其工作之前。

我该如何等待 someService.asyncMethod(testData)在验证结果之前完成?注意 How do I write a unit test to verify async behavior using Spring 4 and annotations? 的解决方案 这里不适用,如 someService.asyncMethod(testData)返回 void ,而不是 Future<?> .

最佳答案

对于要遵守的 @Async 语义,some active @Configuration class will have the @EnableAsync annotation ,例如

@Configuration
@EnableAsync
@EnableScheduling
public class AsyncConfiguration implements AsyncConfigurer {

  //

}

为了解决我的问题,我引入了一个新的 Spring 配置文件non-async

如果 non-async 配置文件处于 Activity 状态,则使用 AsyncConfiguration:

@Configuration
@EnableAsync
@EnableScheduling
@Profile("!non-async")
public class AsyncConfiguration implements AsyncConfigurer {

  // this configuration will be active as long as profile "non-async" is not (!) active

}

如果非异步配置文件处于 Activity 状态,则使用 NonAsyncConfiguration:

@Configuration
// notice the missing @EnableAsync annotation
@EnableScheduling
@Profile("non-async")
public class NonAsyncConfiguration {

  // this configuration will be active as long as profile "non-async" is active

}

现在在有问题的 JUnit 测试类中,我显式激活了“非异步”配置文件以相互排除异步行为:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
@WebAppConfiguration
@IntegrationTest
@Transactional
@ActiveProfiles(profiles = "non-async")
public class SomeServiceIntTest {

    @Inject
    private SomeService someService;

        @Test
        public void testAsyncMethod() {

            Foo testData = prepareTestData();

            someService.asyncMethod(testData);

            verifyResults();
        }

        // verifyResult() with assertions, etc.
}

关于java - JUnit 测试 Spring @Async void 服务方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42438862/

相关文章:

java - 为什么我对这组代码的 JUnit 测试总是返回错误?

java - Robotium:如何在继续之前等待加载完成?

java - 单元测试中的模拟域实体

java - 如何从 Java 主页中抓取某个项目(包括 jsoup)

java - Hibernate 将 NULL 插入原始类型字段

java - 获取 'java.security.cert.CertPathValidatorException: timestamp check failed' 但证书未过期并且在其他服务器上工作

java - 使用 HibernateTemplate 和 IN 子句进行批量更新

java - 我们可以在 Web 服务类中实现方法重载吗?

java - 带有 boolean 字段的 Spring JPA 抛出 "cannot resolve property exception"

spring - 无法为 Spring Controller 的 JUnit 测试加载 ApplicationContext