0

I have a service class that I would like to perform the integration test (whitebox). The method code,

   @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 );
        }
    }

The method that test is provided below,

@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 );


}

I would like to validate the response data, The method invokeEllaAsync returns void. The response is inside the method callEllaService.

How do I validate the response data?

Arefe
  • 11,321
  • 18
  • 114
  • 168

1 Answers1

0

First of all, a quick googling reveals this question. Since I'm not 100% you're talking about Spring indeed, I don't suggest to consider this as a duplication.

Now I'll provide a couple of additional techniques, assuming we're talking about Spring's Async methods (the integration test is probably run with SpringRunner)

To start from the basics, in a nutshell, @Async methods are executed on the different thread pool. Technically it's done by generating a runtime proxy. So there are many techniques (out of my head, since I didn't really use them) that could help:

Option 1

Disable an Async Support for tests. This can be done by creating some kind of condition on your custom configuration class that will enable async support. Something like this:

 @Configuration
 @EnableAsync
 @ConditionalOnProperty(name = "async.support.enabled", havingValue = true)
 public class MyAsyncEnablerConfiguration {

 }

For tests make the variable false

Option 2

If its a method on a controller and you use mockMvc testing (again, only my speculation, I don't know where the code really is), you can take advantage of asyncDispatch method that will take care of asynchronous requests.

It looks like this:

mockMvc.perform(asyncDispatch(mvcResult)) // <-- Note this call
                    .andExpect(status().isOk())
                ...

A full example can be found Here

Option 3

Note that the return type of @Async method doesn't have to be void. It can be Future or even spring's AsyncResult. So if its a future - you could call future.get() in the code and get the result.

To read about the return result types more check This tutorial

Mark Bramnik
  • 39,963
  • 4
  • 57
  • 97
  • Thanks a lot. Do you know an example with the `Wiremock` ? – Arefe Jun 29 '19 at 05:16
  • 1
    No, sorry, but since Wiremock is used to mock the external service call which is by itself is not async or something, I don't think its relevant here as long as you don't want to verify that mock call. – Mark Bramnik Jun 29 '19 at 05:19
  • I have a question. Do I need to keep enable async support for the config file with the LOC ` @ConditionalOnProperty(name = "async.support.enabled", havingValue = true)` and in the test file ` @ConditionalOnProperty(name = "async.support.enabled", havingValue = false)` ? – Arefe Jun 29 '19 at 05:32