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.
Advertisement
Answer
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.