pact-jvm icon indicating copy to clipboard operation
pact-jvm copied to clipboard

Exception when no pacts to verify & test template has also an `HttpRequest` parameter

Open fragonib opened this issue 2 years ago • 6 comments

When there is no PACTs to verify (that satisfy the constraints) PactVerificationContext context is null. The prefered solution is to check that. But if TestTemplate method has also an HttpRequest parameter like:

    @TestTemplate
    @ExtendWith(PactVerificationSpringProvider.class)
    void pactVerificationTestTemplate(PactVerificationContext context, HttpRequest request) throws ProtocolException {
        if (context != null) { // Can be null when there are no PACT defined on Broker
            removeContextFromRequestPath(request);
            context.verifyInteraction();
        }
    }

It throws:

org.junit.jupiter.api.extension.ParameterResolutionException: No ParameterResolver registered for parameter [org.apache.hc.core5.http.HttpRequest request] in method [pactVerificationTestTemplate(au.com.dius.pact.provider.junit5.PactVerificationContext,org.apache.hc.core5.http.HttpRequest) throws org.apache.hc.core5.http.ProtocolException].

When this HttpRequest is removed it logs expected No pact found to verify

Any thoughts?

Originally posted by @fragonib in https://github.com/pact-foundation/pact-jvm/issues/768#issuecomment-1139506120

fragonib avatar May 27 '22 11:05 fragonib

The problem is that to know if it can inject an HTTP request, it needs to know the type of the interaction, but there is no Pact files, so it does not know that and there won't be any request object to inject.

rholshausen avatar Jun 14 '22 05:06 rholshausen

We just migrated from pact version 4.2.7 (where it was working fine without any pacts to verify) to 4.4.3 and encountered this problem.

jamescookie avatar Jan 09 '23 09:01 jamescookie

So what changed from 4.2 to also 4.5 that this can't be detected anymore?

vghero avatar Mar 10 '23 09:03 vghero

With 4.2.x, there was only one type of interaction. With 4.5.x, there can be multiple types of interactions.

rholshausen avatar Mar 20 '23 01:03 rholshausen

As a workaround I just added this ParameterResolver and registered it via ExtendWith to my test base class:

public class PactNoPactsWorkaround implements ParameterResolver {
    @Override
    public boolean supportsParameter(final ParameterContext parameterContext, final ExtensionContext extensionContext)
            throws ParameterResolutionException {
        final ExtensionContext.Store store = extensionContext.getStore(ExtensionContext.Namespace.create("pact-jvm"));
        final PactVerificationContext testContext = (PactVerificationContext) store.get("interactionContext");
        return testContext == null && parameterContext.getParameter().getType() == HttpRequest.class;
    }

    @Override
    public Object resolveParameter(final ParameterContext parameterContext, final ExtensionContext extensionContext)
            throws ParameterResolutionException {
        return null;
    }
}

holomekc avatar May 12 '23 04:05 holomekc

I used this workaround, maybe it helps someone.

Create Junit5 extension to ignore ParameterResolutionException:

class IgnoreParameterResolutionException implements TestExecutionExceptionHandler {
    @Override
    public void handleTestExecutionException(ExtensionContext extensionContext, Throwable throwable) throws Throwable {
        if (throwable instanceof ParameterResolutionException) {
            return;
        }
        throw throwable;
    }
}

Use it on @TestTemplate method:

@TestTemplate
@ExtendWith({PactVerificationSpringProvider.class, IgnoreParameterResolutionException.class})
void pactVerificationTestTemplate(PactVerificationContext context, MockHttpServletRequestBuilder requestBuilder) {
    requestBuilder
            .with(csrf())
            .contextPath(servletContextPath);
    if (context != null) {
        context.verifyInteraction();
    }
}

dynnoil avatar Apr 04 '24 08:04 dynnoil