为服务编写集成测试

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