Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dropwizard Integrated Testing with TestResource

Does anyone knows how to add a test Resource (i.e. one that is only for testing purposes and not added in run() method of the app)?

Here is an example:

public class MyTest {   
    @ClassRule
    public static final DropwizardAppRule<TestConfiguration> RULE =
            new DropwizardAppRule<TestConfiguration>(MyApp.class, "my-app-config.yaml");


    @BeforeClass
    public static void setUpBeforeClass() throws Exception
    {
        MyTest.RULE.getEnvironment().jersey().register(new JustForTestingResource());
    }


    @Test
    public final void testTestResource()
    {
        Client client = new Client();

        ClientResponse response = client.resource(
            String.format("http://localhost:%d/rest/v1/test", RULE.getLocalPort()))
            .get(ClientResponse.class);

        assertThat(response.getStatus(), is(200));   
    }
}

and

public class JustForTestingRessource {


    @GET
    @Path("test")
    @Produces(MediaType.APPLICATION_JSON)
    public Response getInTestResource()
    {
        return Response.status(Status.OK).type(MediaType.TEXT_PLAIN).entity("get @Path(\"test\") is ok").build();
    }
}

My problem is that the added resource is not added and I get resource not found 404 error response. It seems that I am registering the new resource after resource publishing and there is no refresh inside Dropwizard after start.

I dont want to extend my Application class and I dont want to insert test code into my real application code. Does anyone knows how to register the test resource without registering it in run() method of the Application?

This works, but a new class is needed:

public class TestService extends MyService{


    @Override
    public void run(
        TestConfigurationconfiguration,
        Environment environment) throws ClassNotFoundException
    {       
        environment.jersey().register(new JustForTestingRessource());
        super.run(configuration,environment);
    }

}

Call in JUnit as already known:

@ClassRule
public static DropwizardAppRule<TestConfiguration> RULE =
        new DropwizardAppRule<TestConfiguration>(TestService.class, "my-app-config.yaml");
like image 579
user3280180 Avatar asked Oct 15 '14 11:10

user3280180


People also ask

How do I test HTTP client code in Dropwizard?

To avoid circular dependencies in your projects or to speed up test runs, you can test your HTTP client code by writing a JAX-RS resource as test double and let the DropwizardClientExtension start and stop a simple Dropwizard application containing your test doubles.

How do I use Dropwizard to test a resourceextension?

Use the @ExtendWith (DropwizardExtensionsSupport.class) annotation on the class to tell Dropwizard to find any field of type ResourceExtension. In your tests, use #target (String path), which initializes a request to talk to and test your instances.

How do I start and stop an app using dropwizardtestsupport?

By creating a DropwizardTestSupport instance in your test you can manually start and stop the app in your tests, you do this by calling its before and after methods. DropwizardTestSupport also exposes the app’s Configuration, Environment and the app object itself so that these can be queried by the tests.

What is the Dropwizard-testing module?

The dropwizard-testing module provides you with some handy classes for testing your representation classes and resource classes. It also provides an extension for JUnit 5.x and a rule for JUnit 4.x.


2 Answers

Edit: Removing previous answer because it didn't solve your problem the way you wanted to do it.

I dug into the environment startup code and realized the reason why registering a controller didn't make it available is because jetty had already been started. If you stop jetty, register your controller and start jetty back up again, your resource will be available and you can use it in your test.

@BeforeClass
public static void setUpBeforeClass() throws Exception
{
    MyTest.RULE.environment.applicationContext.stop()
    MyTest.RULE.environment.jersey().register(new JustForTestingResource())
    MyTest.RULE.environment.applicationContext.start()
}
like image 122
th3morg Avatar answered Sep 19 '22 11:09

th3morg


You can test the Resource itself in a Jersey Container without starting a full dw-instance.

Check the "Testing Resources" section.

import static org.fest.assertions.api.Assertions.assertThat;
import static org.mockito.Mockito.*;

public class PersonResourceTest {

     private static final PeopleStore dao = mock(PeopleStore.class);

     @ClassRule
     public static final ResourceTestRule resources = ResourceTestRule.builder()
        .addResource(new PersonResource(dao))
        .build();

     private final Person person = new Person("blah", "[email protected]");

     @Before
     public void setup() {
         when(dao.fetchPerson(eq("blah"))).thenReturn(person);
         // we have to reset the mock after each test because of the
         // @ClassRule, or use a @Rule as mentioned below.
         reset(dao);
     }

     @Test
     public void testGetPerson() {
         assertThat(resources.client().resource("/person/blah").get(Person.class))
            .isEqualTo(person);
         verify(dao).fetchPerson("blah");
     }
 }
like image 32
Jan Galinski Avatar answered Sep 19 '22 11:09

Jan Galinski