Barry
Barry

Reputation: 1820

unit testing @Suspended AsyncResponse controller

I am upgrading to be fully asynchronous and I have an exsiting test that unit tests the controller with mocked dependencies and tests the various paths. I can't figure out how to convert this unit test. I am using dropwizard/jersey and the method I want to test looks like this now

 @POST
public void getPostExample(final Map body, @Suspended final AsyncResponse
 asyncResponse){}

The old test uses mockito/junit and uses @InjectMocks for the controller which it then calls the method on getPostExample and asserts some info on the response. The services it calls are mocked but I can't find much when I search for how to manually get this to return data. I can get access to the AsyncResponse but in the real code that calls the resume with results. Should I be calling resume in my test?

Upvotes: 6

Views: 3220

Answers (2)

DLV
DLV

Reputation: 1

Add mockito after() method call to wait for the other thread to finish; that should resolve issue with exception, f.e.: Mockito.verify(response, after(10000)).resume(this.captor.capture());

Upvotes: 0

Paul Samsotha
Paul Samsotha

Reputation: 209052

"Should I be calling resume in my test". No. What you should do is test that the resume method is called with the expected arguments. This is how you test the behavior of the method.

What you can do is use Mockito's ArgumentCaptor to capture the Response that is passed to the resume method, and then make your assertions on that Response. You will need to mock the AsyncResponse for this to work. Below is an example

@RunWith(MockitoJUnitRunner.class)
public class AsyncMockTest {

    @Mock
    private AsyncResponse response;

    @Captor
    private ArgumentCaptor<Response> captor;

    @Test
    public void testAsyncResponse() {
        final TestResource resource = new TestResource();
        resource.get(this.response);

        Mockito.verify(this.response).resume(this.captor.capture());
        final Response res = this.captor.getValue();

        assertThat(res.getEntity()).isEqualTo("Testing");
        assertThat(res.getStatus()).isEqualTo(200);
    }

    @Path("test")
    public static class TestResource {
        @GET
        @ManagedAsync
        public void get(@Suspended AsyncResponse response) {
            response.resume(Response.ok("Testing").build());
        }
    }
}

Upvotes: 8

Related Questions