You could delay the initialization of the resource class until after you've set up your mocks:
private final MockitoTestRule mockitoTestRule = new MockitoTestRule(this, MockitoJUnit.rule()); private final ResourceTestRule resourceTestRule = ResourceTestRule.builder() .addResource(this::setupResource) .build(); @Rule public final RuleChain ruleChain = RuleChain.outerRule(mockitoTestRule).around(resourceTestRule); @Mock private DemoConfiguration demoConfiguration; public PersonResource setupResource() { when(demoConfiguration.getFoo()).thenReturn("me"); when(demoConfiguration.getBar()).thenReturn("me too"); return new DemoResource(demoConfiguration); }Please be aware that Dropwizard 1.3.2 is more than 2 years old and you should migrate to the latest version in that version line (Dropwizard 1.3.23) or even better to the latest stable version (Dropwizard 2.0.10) instead.
Am 12.06.2020 um 02:21 schrieb jaywhy <john....@gmail.com>:I've going through a legacy dropwizard (v1.3.2) codebase where given the following Configuration:public class DemoConfiguration extends Configuration {
@Valid
@Getter
@NotNull
@JsonProperty("foo")
private String foo;
@Valid
@Getter
@NotNull
@JsonProperty("bar")
private String bar;
// Many others
...
}and the following Resource:package com.demo;
import java.util.HashMap;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
@Path("/")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class DemoResource {
private String foo;
private String bar;
public DemoResource(DemoConfiguration config) {
this.foo = config.getFoo();
this.bar = config.getBar();
checkNullOrEmpty(foo);
checkNullOrEmpty(bar);
// Many other questionable decisions
...
}
@GET
@Path("/demo")
public HashMap<String, String> getHealth() {
HashMap<String, String> map = new HashMap<>();
map.put("foo", foo);
map.put("bar", bar);
return map;
}
}Above, for brevity sake i've only included one parameter in the constructor, but imagine a constructor with over 70 parameters (Configuration, Dao..etc) that are used and validated within the constructor itself!To test the above resource, I'm trying to do the below:public class DemoResourceTest {
private static final DemoConfiguration demoConfiguration = mock(DemoConfiguration.class);
@ClassRule
public static final ResourceTestRule resources = ResourceTestRule.builder()
.addResource(new DemoResource(demoConfiguration))
.build();
@Before
public void setup() {
when(demoConfiguration.getFoo()).thenReturn("me");
when(demoConfiguration.getBar()).thenReturn("me too");
}
@Test
public void demoTest() {
Response rsp = resources.target("/demo").request().get();
assertThat(rsp.getStatus()).isEqualTo(200);
}
}The test fail, because @ClassRule is called first which initializes the DemoResource before I've had the chance to set the values for the mock (which happen in the @Before step).Is there a way to make this work, where i can setup and pass the mocked instance of DemoConfiguration to the constructor of DemoResource? The alternative would be to create an instance of every single one of those Configuration (and other deps) passed into the constructor manually which would be impossible given the no. of properties.--
You received this message because you are subscribed to the Google Groups "dropwizard-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to dropwizard-us...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/dropwizard-user/380b19d1-f5bd-4aa2-bf6a-141cd6df6774o%40googlegroups.com.