编程语言
首页 > 编程语言> > java – JUnit测试Spring @Async void服务方法

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

作者:互联网

我有一个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线程将调用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配置文件非异步.

如果非异步配置文件未激活,则使用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

}

如果非同步配置文件处于活动状态,则使用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,spring,junit,spring-async
来源: https://codeday.me/bug/20191004/1853327.html