Hot questions for Using Mockito in dropwizard

Question:

I am trying to test dropwizard resources and followed http://www.dropwizard.io/manual/testing.html to do so.

However, I always get a null object from the mocked class/method.

The resource method

    @GET
    @Path("/id")
    @ApiOperation("Find property by id")
    @Produces(MediaType.APPLICATION_JSON)
    public Property findById(@QueryParam("id") int id) {

        return propertyDAO.findById(id);
    }

And the test class

public class PropertiesResourceTest {

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

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

    private final Property property = new Property(1);

    @Before
    public void setUp() {

        when(dao.findById(eq(1))).thenReturn(property);
        reset(dao);
    }

    @Test
    public void findById() {
        assertThat(resources.client().target("/properties/id?id=1").request().get(Property.class))
                .isEqualTo(property);
        verify(dao).findById(1);
    }

}

I tried to spin it in many ways, but the result is always the same:

expected:<Property | ID: 1 > but was:<null>

Do you have any leads on why mockito is always returning a null object ?


Answer:

when(dao.findById(eq(1))).thenReturn(property);
reset(dao);

The first line stubs calls to findById. The second line, reset, immediately deletes that stubbing. You may want to swap the order of those two statements.

Though keeping mocks in static variables is a dangerous habit, and though the documentation is right to suggest you call reset manually, it is important to do so before you set expectations (i.e. as the first line in your @Before method) or after the test completes (i.e. as the last line in your @After method). Otherwise Mockito will find no stubbing there and will return its default value null.

I would recommend following their suggestion of removing the static modifier and using @Rule instead of @ClassRule. It is much less likely to inadvertently cause test pollution.

It is extremely bizarre that the documentation you linked has that code sample with the methods in that order. It should probably be updated.

Question:

I am starting a fresh Dropwizard project and I am not able to use MockitoJUnitRunner to run tests.

I am able to run the main application. So, I am guessing that it is not a JRE/JDK problem.

Here are a few files from my project:

pom.xml

<dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13</version>
            <scope>test</scope>
</dependency>

FooTest.java (For the sake of simplicity, I removed logic.)

import org.junit.Test;

import org.junit.runner.RunWith;

@RunWith(MockitoJUnitRunner.class)
class FooTest {
  @Test
  public void testSout() {
    System.out.println("This tests works.");
  }
}

I am getting the following error.

Error:(20, 10) java: cannot find symbol symbol: class MockitoJUnitRunner


Answer:

First add the dependency to Mockito to you project, second import the class from the proper location.

<dependency>
  <groupId>org.mockito</groupId>
  <artifactId>mockito-core</artifactId>
  <version>3.2.4</version>
  <scope>test</scope>
</dependency>

In your class do the proper import.

import org.mockito.junit.MockitoJUnitRunner;

NOTE: Your code doesn't really use any of the Mockito annotations like @Mock or @Spy so not sure why you even want to run it with the special mockito runner. Currently it will only slow down your test runs.

Question:

I'm using dropwizard and now i'm stuck. When i added new bundle, which give's me data from other source, my resource test cases are failing, because i dont know how to test my resource now. I've tried using mockito, but it didn't work anyway.

So here's my question - how to initialize bundle in my test class so my test objects would be able to get data from bundle correctly? Or maybe you would have other solutions to this problem?


Answer:

For testing dropwizard resource use dropwizard-testing package. With this you can define class rule and start up your context for tests:

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

Also you can test resources without up context with ResourceTestRule class.