为服务编写集成测试
Writing an integration test for a service
我有一项服务 class 我想执行集成测试(白盒)。方法代码,
@Async( ELLA_THREAD_POOL_EXECUTOR_NAME )
public void invokeEllaAsync( final IrisBo irisBo ) {
if( isTrafficAllowed( irisBo ) ) {
callEllaService( irisBo );
}
}
public void callEllaService( final IrisBo irisBo ) {
HttpHeaders ellaHeaders = createRequestHeaders( irisBo );
ServiceResponse<EllaResponseDto> response = connector.call( EllaDtoConverter.convertToRequest( irisBo ), ellaHeaders );
if( !response.isSuccess() ) {
LOG.error( "ERROR", response, irisBo );
}
}
下面给出测试方法,
@Test
public void testCallEllaServiceIsSuccessful() throws IOException {
String emailAgeResponseJson = readFile( ELLA_RESPONSE_FILE );
wireMockRule.stubFor( post( urlEqualTo( ELLA_ENDPOINT ) ).willReturn( okJson( emailAgeResponseJson ) ) );
TestRequestInformation testRequestInformation = new TestRequestInformation();
IrisBo irisBo = EllaTestDataProvider.createValidIrisBoWithoutRequest();
service.callEllaService( irisBo );
}
我想验证响应数据,方法invokeEllaAsync
returns void
。响应在方法 callEllaService
内。
如何验证响应数据?
首先,快速谷歌搜索显示 。由于我不是 100% 确实在谈论 Spring,我不建议将其视为重复。
现在我将提供一些额外的技术,假设我们正在谈论 Spring 的异步方法(集成测试可能是 运行 和 SpringRunner
)
从基础开始,简而言之,@Async
方法在不同的线程池上执行。从技术上讲,它是通过生成 运行 时间代理来完成的。
所以有很多技巧(我想不出来,因为我并没有真正使用过)可以提供帮助:
选项 1
禁用测试的异步支持。这可以通过在自定义配置 class 上创建某种条件来启用异步支持来完成。像这样:
@Configuration
@EnableAsync
@ConditionalOnProperty(name = "async.support.enabled", havingValue = true)
public class MyAsyncEnablerConfiguration {
}
对于测试使变量false
选项 2
如果它是控制器上的一个方法并且您使用 mockMvc 测试(同样,这只是我的猜测,我不知道代码到底在哪里),您可以利用 asyncDispatch
方法处理异步请求。
看起来像这样:
mockMvc.perform(asyncDispatch(mvcResult)) // <-- Note this call
.andExpect(status().isOk())
...
可以找到完整的示例Here
选项 3
请注意,@Async
方法的 return 类型不一定是 void
。它可以是 Future
甚至 spring 的 AsyncResult
。
因此,如果它是未来 - 您可以在代码中调用 future.get()
并获得结果。
要阅读有关 return 结果类型的更多信息,请检查 This tutorial
我有一项服务 class 我想执行集成测试(白盒)。方法代码,
@Async( ELLA_THREAD_POOL_EXECUTOR_NAME )
public void invokeEllaAsync( final IrisBo irisBo ) {
if( isTrafficAllowed( irisBo ) ) {
callEllaService( irisBo );
}
}
public void callEllaService( final IrisBo irisBo ) {
HttpHeaders ellaHeaders = createRequestHeaders( irisBo );
ServiceResponse<EllaResponseDto> response = connector.call( EllaDtoConverter.convertToRequest( irisBo ), ellaHeaders );
if( !response.isSuccess() ) {
LOG.error( "ERROR", response, irisBo );
}
}
下面给出测试方法,
@Test
public void testCallEllaServiceIsSuccessful() throws IOException {
String emailAgeResponseJson = readFile( ELLA_RESPONSE_FILE );
wireMockRule.stubFor( post( urlEqualTo( ELLA_ENDPOINT ) ).willReturn( okJson( emailAgeResponseJson ) ) );
TestRequestInformation testRequestInformation = new TestRequestInformation();
IrisBo irisBo = EllaTestDataProvider.createValidIrisBoWithoutRequest();
service.callEllaService( irisBo );
}
我想验证响应数据,方法invokeEllaAsync
returns void
。响应在方法 callEllaService
内。
如何验证响应数据?
首先,快速谷歌搜索显示
现在我将提供一些额外的技术,假设我们正在谈论 Spring 的异步方法(集成测试可能是 运行 和 SpringRunner
)
从基础开始,简而言之,@Async
方法在不同的线程池上执行。从技术上讲,它是通过生成 运行 时间代理来完成的。
所以有很多技巧(我想不出来,因为我并没有真正使用过)可以提供帮助:
选项 1
禁用测试的异步支持。这可以通过在自定义配置 class 上创建某种条件来启用异步支持来完成。像这样:
@Configuration
@EnableAsync
@ConditionalOnProperty(name = "async.support.enabled", havingValue = true)
public class MyAsyncEnablerConfiguration {
}
对于测试使变量false
选项 2
如果它是控制器上的一个方法并且您使用 mockMvc 测试(同样,这只是我的猜测,我不知道代码到底在哪里),您可以利用 asyncDispatch
方法处理异步请求。
看起来像这样:
mockMvc.perform(asyncDispatch(mvcResult)) // <-- Note this call
.andExpect(status().isOk())
...
可以找到完整的示例Here
选项 3
请注意,@Async
方法的 return 类型不一定是 void
。它可以是 Future
甚至 spring 的 AsyncResult
。
因此,如果它是未来 - 您可以在代码中调用 future.get()
并获得结果。
要阅读有关 return 结果类型的更多信息,请检查 This tutorial