2

I am trying to test a Dropwizard resource.

My test looks like this:

@ExtendWith(DropwizardExtensionsSupport.class)
public class CommonObjectsTest {
    private ResourceExtension EXT;

    @BeforeEach
    public void setup() {
        ApplicationConfig applicationConfig = mock(ApplicationConfig.class);
        when(applicationConfig.getYears()).thenReturn(1);

        MyAppConfig myAppConfig = mock(MyAppConfig.class);
        when(myAppConfig.getAppConfig()).thenReturn(applicationConfig);

        EmailClient emailClient = mock(EmailClient.class);
        CommonObjects commonObjects = new CommonObjects(myAppConfig, emailClient);

        EXT = ResourceExtension.builder()
                .addResource(commonObjects)
                .build();
    }

    @Test
    public void getYearsSuccessfully() {
        Response response = EXT.target("/get_years").request().get();
        System.out.println(response);
    }
}

However, this gives the error message:

java.lang.NullPointerException
    at io.dropwizard.testing.junit5.DropwizardExtensionsSupport.beforeEach(DropwizardExtensionsSupport.java:123)
    at io.dropwizard.testing.junit5.DropwizardExtensionsSupport.beforeEach(DropwizardExtensionsSupport.java:106)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeBeforeEachCallbacks$1(TestMethodTestDescriptor.java:159)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeBeforeMethodsOrCallbacksUntilExceptionOccurs$5(TestMethodTestDescriptor.java:195)
    ...

which is frankly uninformative. Can someone point out what is wrong here?

P/S Here is the CommonObjects constructor:

    public CommonObjects(MyAppConfig configuration, EmailClient emailClient) {
        ApplicationConfig appConfig = configuration.getAppConfig();
        this.years = appConfig.getYears();
        this.emailClient = emailClient;
    }

which also explains why I am creating the resource extension before each test case.

umop apisdn
  • 653
  • 9
  • 20
  • `private ResourceExtension EXT;` field have to be non null at the time time of `beforeEach` lifecycle precoessing to work properly with dropwizard extension. Initialize it at the declaration. – Yurii Melnychuk Jun 30 '21 at 09:40
  • [Official documentation](https://www.dropwizard.io/en/latest/manual/testing.html#testing-resources) on resource testing can help. – Yurii Melnychuk Jun 30 '21 at 09:41
  • @YuriiMelnychuk I read the documentation before. Thanks for explaining the error. Do you have any suggestion on how I can initialise it at declaration given that I have to access methods on the mock objects provided to the `CommonObjects` constructor? – umop apisdn Jul 01 '21 at 00:28

2 Answers2

1

This may not be the solution to this answer, however I had a similar exception with the bonehead problem of running the extension in vintage JUnit rather than Jupiter which is required for the ExtendWith annotation. Maybe this will save someone an hour or two.

NullPointerException:

import org.junit.Test;

Works:

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
Phillip Fleischer
  • 1,023
  • 12
  • 14
0

In the end, instead of using mocks, I created stubs extending from concrete classes.

For example, for ApplicationConfig, I created ApplicationConfigStub:

public class ApplicationConfigStub extends ApplicationConfig {
    @Override
    public int getYears() {
        return 1;
    }
}

And for MyAppConfig, I created MyAppConfigStub:

public class MyAppConfigStub extends MyAppConfig {
    @Override
    public ApplicationConfig getAppConfig() {
        return new ApplicationConfigStub();
    }
}

Then, I used these stubs when initialising the ResourceExtension in the test class:

private static final EmailClient emailClient = mock(EmailClient.class);
private static final ResourceExtension EXT = ResourceExtension.builder()
            .addResource(new CommonObjects(new MyAppConfigStub(), emailClient))
            .build();

This would allow for the resource extension to be initialised at declaration even if we are calling methods in other dependencies during the initialisation.

umop apisdn
  • 653
  • 9
  • 20