Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DropwizardExtensionSupport multiple extensions cannot be ordered #3549

Closed
jaredculp opened this issue Nov 3, 2020 · 1 comment
Closed

DropwizardExtensionSupport multiple extensions cannot be ordered #3549

jaredculp opened this issue Nov 3, 2020 · 1 comment
Milestone

Comments

@jaredculp
Copy link

jaredculp commented Nov 3, 2020

I'd like to be able to set up a stub DropwizardClientExtension to mock an upstream service that my dropwizard app is dependent on. This was possible in junit4 but does not appear possible in junit5.

@Path("/")
public static final class Resource {
  @GET
  public Response response() {
    return Response.ok().build();
  }
}
public static final DropwizardClientExtension UPSTREAM = new DropwizardClientExtension(new Resource());

public static final DropwizardAppExtension<Configuration> APP =
    new DropwizardAppExtension<>(
        Application.class,
        ResourceHelpers.resourceFilePath("configuration.yml"),
        ConfigOverride.config("dependentServiceUrl", () -> UPSTREAM.baseUri().toString()));

This fails with a NPE:

java.lang.RuntimeException: java.lang.NullPointerException

	at io.dropwizard.testing.junit5.DropwizardExtensionsSupport.beforeAll(DropwizardExtensionsSupport.java:63)
	at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeBeforeAllCallbacks$7(ClassBasedTestDescriptor.java:355)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.invokeBeforeAllCallbacks(ClassBasedTestDescriptor.java:355)
	at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.before(ClassBasedTestDescriptor.java:189)
	at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.before(ClassBasedTestDescriptor.java:77)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:132)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1540)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
	at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
	at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:248)
	at org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$5(DefaultLauncher.java:211)
	at org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:226)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:199)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:132)
	at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:71)
	at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
	at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:220)
	at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:53)
	Suppressed: java.lang.RuntimeException: java.lang.NullPointerException
		at io.dropwizard.testing.junit5.DropwizardExtensionsSupport.afterAll(DropwizardExtensionsSupport.java:39)
		at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeAfterAllCallbacks$13(ClassBasedTestDescriptor.java:421)
		at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
		at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeAfterAllCallbacks$14(ClassBasedTestDescriptor.java:421)
		at java.base/java.util.ArrayList.forEach(ArrayList.java:1540)
		at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.invokeAfterAllCallbacks(ClassBasedTestDescriptor.java:421)
		at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.after(ClassBasedTestDescriptor.java:213)
		at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.after(ClassBasedTestDescriptor.java:77)
		at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:145)
		at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
		at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:145)
		... 27 more

In junit4 we could use a rule chain in order to specify the order of these dependencies; however adding @Order to these two fields does not appear to work.

@jaredculp
Copy link
Author

jaredculp commented Nov 3, 2020

I am able to work around it with these two classes:

import io.dropwizard.Application;
import io.dropwizard.Configuration;
import io.dropwizard.testing.ConfigOverride;
import org.junit.jupiter.api.extension.AfterAllCallback;
import org.junit.jupiter.api.extension.BeforeAllCallback;
import org.junit.jupiter.api.extension.ExtensionContext;

public class DropwizardAppExtension<C extends Configuration> extends
    io.dropwizard.testing.junit5.DropwizardAppExtension<C> implements BeforeAllCallback,
    AfterAllCallback {

  public DropwizardAppExtension(Class<? extends Application<C>> applicationClass,
      String resourceFilePath, ConfigOverride... configOverrides) {
    super(applicationClass, resourceFilePath, configOverrides);
  }

  @Override
  public void beforeAll(ExtensionContext context) throws Exception {
    super.before();
  }

  @Override
  public void afterAll(ExtensionContext context) throws Exception {
    super.after();
  }
}
import org.junit.jupiter.api.extension.AfterAllCallback;
import org.junit.jupiter.api.extension.BeforeAllCallback;
import org.junit.jupiter.api.extension.ExtensionContext;

public class DropwizardClientExtension extends
    io.dropwizard.testing.junit5.DropwizardClientExtension implements BeforeAllCallback,
    AfterAllCallback {

  public DropwizardClientExtension(Object... resources) {
    super(resources);
  }

  @Override
  public void beforeAll(ExtensionContext context) {
    try {
      super.before();
    } catch (Throwable throwable) {
      throw new RuntimeException(throwable);
    }
  }

  @Override
  public void afterAll(ExtensionContext context) {
    super.after();
  }
}

and changing the snippet above to no longer use @ExtendWith(DropwizardExtensionSupport.class) and instead:

  @Path("/")
  public static final class Resource {
    @GET
    public Response response() {
      return Response.ok().build();
    }
  }

  @RegisterExtension
  @Order(1)
  public static final DropwizardClientExtension UPSTREAM = new DropwizardClientExtension(new Resource());

@RegisterExtension
@Order(2)
public static final DropwizardAppExtension<Configuration> APP =
    new DropwizardAppExtension<>(
        Application.class,
        ResourceHelpers.resourceFilePath("configuration.yml"),
        ConfigOverride.config("dependentServiceUrl", () -> UPSTREAM.baseUri().toString()));

Is there a reason that the dropwizard extensions don't implement the junit5 interfaces directly like this?

@joschi joschi added this to the 2.0.17 milestone Nov 26, 2020
@joschi joschi modified the milestones: 2.0.17, 2.0.18 Dec 14, 2020
@joschi joschi closed this as completed in 639f030 Jan 11, 2021
joschi pushed a commit that referenced this issue Jan 11, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants