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

PactConsumerTestExt failure with JUnit Jupiter Parameter Resolving in @BeforeAll #1643

Open
rieckpil opened this issue Nov 25, 2022 · 2 comments
Labels
bug Indicates an unexpected problem or unintended behavior

Comments

@rieckpil
Copy link

rieckpil commented Nov 25, 2022

Hey 👋🏻,

We're doing some setup work in our @BeforeAll method and inject various parameters to the lifecycle method that get resolved by other JUnit Jupiter extensions. However, our test fail because when it's the turn of the PactConsumerTestExt to determine if this extension is responsible for resolving the parameter, it expects a test method to be present in the context. That's not the case as no method has been selected yet as we're in the @BeforeAll lifecylce.

I tested it with JUnit 5.9.0 and au.com.dius.pact.consumer 4.4.2 and get the following exception:

org.junit.jupiter.api.extension.ParameterResolutionException: Failed to resolve parameter [java.lang.String arg0] in method [static void de.rieckpil.blog.SamplePactTest.setup(java.lang.String)]: Illegal state: required test method is not present in the current ExtensionContext
        at org.junit.jupiter.engine.execution.ParameterResolutionUtils.resolveParameter(ParameterResolutionUtils.java:159)
        at org.junit.jupiter.engine.execution.ParameterResolutionUtils.resolveParameters(ParameterResolutionUtils.java:103)
        // ...
Caused by: org.junit.platform.commons.PreconditionViolationException: Illegal state: required test method is not present in the current ExtensionContext
        at org.junit.platform.commons.util.Preconditions.condition(Preconditions.java:299)
        at org.junit.platform.commons.util.Preconditions.notNull(Preconditions.java:55)
        at org.junit.jupiter.api.extension.ExtensionContext.getRequiredTestMethod(ExtensionContext.java:241)
        at au.com.dius.pact.consumer.junit5.PactConsumerTestExt.lookupProviderInfo(PactConsumerTestExt.kt:271)
        at au.com.dius.pact.consumer.junit5.PactConsumerTestExt.supportsParameter(PactConsumerTestExt.kt:57)
        at org.junit.jupiter.engine.execution.ParameterResolutionUtils.lambda$resolveParameter$0(ParameterResolutionUtils.java:114)
       // ...
        at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:682)
        at org.junit.jupiter.engine.execution.ParameterResolutionUtils.resolveParameter(ParameterResolutionUtils.java:115)

A minimal test example looks like the following:

@ExtendWith({PactConsumerTestExt.class, MyStringResolverExtension.class})
@PactTestFor(providerName = "some-provider", providerType = ProviderType.ASYNCH)
class SamplePactTest {

  @BeforeAll
  // when evaluating whether or not the PactConsumerTestExt is responsible for this parameter, the extension fails
  static void setup(String injectedString) {
    System.out.println(injectedString);
  }

  @Pact(consumer = "some-consumer")
  public MessagePact someMessage(MessagePactBuilder builder) {
    return builder.withContent(LambdaDsl.newJsonBody(object -> object.stringType("test", "Test")).build()).toPact();
  }

  @Test
  @PactTestFor(pactMethod = "someMessage")
  void consume(List<Message> messages) {
    System.out.println(messages);
  }
}

I assume that there's no context.requiredTestMethod present at this time of the lifecycle as the JUnit Jupiter lifecycle method is called before any test method.

  fun lookupProviderInfo(context: ExtensionContext): List<Pair<ProviderInfo, String>> {
    logger.trace { "lookupProviderInfo($context)" }
    val store = context.getStore(NAMESPACE)
    val providerInfo = when {
      store["providers"] != null -> store["providers"] as List<Pair<ProviderInfo, String>>
      else -> {
        val methodAnnotation = if (AnnotationSupport.isAnnotated(context.requiredTestMethod, PactTestFor::class.java)) {

I created a minimal reproducible example here.

We tried to explicitly order the extension but even though an extension reports it's responsible for resolving a parameter, still all other extensions in the chain are asked if they support the parameter.

A current workaround is to use @BeforeEach where it works as there's already a selected test method. However, that's not suitable as we want our test setup work to be done only once for a test.

@rholshausen
Copy link
Contributor

/jira create

@rholshausen rholshausen added the bug Indicates an unexpected problem or unintended behavior label Jan 4, 2023
@github-actions
Copy link

github-actions bot commented Jan 4, 2023

👋 Thanks, Jira [PACT-475] ticket created.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Indicates an unexpected problem or unintended behavior
Projects
None yet
Development

No branches or pull requests

2 participants