Issue
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.
Solution
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.
Answered By - umop apisdn
Answer Checked By - Candace Johnson (JavaFixing Volunteer)