我有一个 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<?>
。
原文由 Abdull 发布,翻译遵循 CC BY-SA 4.0 许可协议
对于
@Async
要遵守的语义, 一些活动的@Configuration
类将具有@EnableAsync
注释,例如为了解决我的问题,我引入了一个新的 Spring 配置文件
non-async
。如果
non-async
配置文件 未 激活,则使用AsyncConfiguration
:如果非异步配置文件处于活动状态, 则 使用
NonAsyncConfiguration
:现在在有问题的 JUnit 测试类中,我显式激活“非异步”配置文件以相互排除异步行为: