pact-foundation / pact-jvm

JVM version of Pact. Enables consumer driven contract testing, providing a mock service and DSL for the consumer project, and interaction playback and verification for the service provider project.
https://docs.pact.io
Apache License 2.0
1.08k stars 478 forks source link

Connection refused using pact-jvm-consumer-junit Rule #1057

Open Thorn1089 opened 4 years ago

Thorn1089 commented 4 years ago

The mock server is not accessible when using the JUnit 4 library. I have no such problems when using the JUnit 5 library on a different project. I am using Retrofit/OkHttp as the HTTP client.

Pausing the unit test at a breakpoint prior to making the call, and calling the corresponding HTTP endpoint manually in Postman results in an infinite hang.

<dependency>
            <groupId>au.com.dius</groupId>
            <artifactId>pact-jvm-consumer-junit</artifactId>
            <version>4.0.8</version>
            <scope>test</scope>
</dependency>
@PactFolder("pacts")
public class ObservationsClientContractTest {

    private static final String ISO_INSTANT_FORMAT = "yyyy-MM-dd'T'HH:mm:ssZ";

    @Rule
    public PactProviderRule mockProvider = new PactProviderRule("dw-service", "localhost", 8080, this);

    @Pact(provider="dw-service", consumer="ws/data")
    public RequestResponsePact createPact(PactDslWithProvider builder) {
        return builder
                .uponReceiving("a request for observations within a range for one or more loggers and a single user")
                .path("/observations")
                .method("GET")
                .willRespondWith()
                .status(200)
                .body(new PactDslJsonBody()
                    .array("observations")
                        .eachLike()
                        .timestamp("timestamp", ISO_INSTANT_FORMAT, Instant.parse("2020-01-01T12:34:56Z"))
                    .closeArray())
                .toPact();
    }

    @Test
    @PactVerification("dw-service")
    public void expectServiceToProvideObservationRange() throws IOException {
        final Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://localhost:8080/")
                .addConverterFactory(JacksonConverterFactory.create())
                .build();

        final ObservationsClient client = retrofit.create(ObservationsClient.class);

        final Call<Object> call = client.fetch();
        final Response<Object> response = call.execute();
    }
}

java.lang.AssertionError: Pact Test function failed with an exception: Failed to connect to localhost/0:0:0:0:0:0:0:1:8080

at au.com.dius.pact.consumer.junit.JUnitTestSupport.validateMockServerResult(JUnitTestSupport.kt:57)
at au.com.dius.pact.consumer.junit.BaseProviderRule.validateResult(BaseProviderRule.java:177)
at au.com.dius.pact.consumer.junit.BaseProviderRule$1.evaluate(BaseProviderRule.java:84)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58)

Caused by: java.net.ConnectException: Failed to connect to localhost/0:0:0:0:0:0:0:1:8080 at okhttp3.internal.connection.RealConnection.connectSocket(RealConnection.java:265) at okhttp3.internal.connection.RealConnection.connect(RealConnection.java:183) at okhttp3.internal.connection.ExchangeFinder.findConnection(ExchangeFinder.java:224) at okhttp3.internal.connection.ExchangeFinder.findHealthyConnection(ExchangeFinder.java:108) at okhttp3.internal.connection.ExchangeFinder.find(ExchangeFinder.java:88) at okhttp3.internal.connection.Transmitter.newExchange(Transmitter.java:169) at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:41) at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:142) at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:117) at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:94) at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:142) at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:117) at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93) at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:142) at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:88) at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:142) at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:117) at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:229) at okhttp3.RealCall.execute(RealCall.java:81) at retrofit2.OkHttpCall.execute(OkHttpCall.java:188) at com.onset.ws.data.observations.test.ObservationsClientContractTest.expectServiceToProvideObservationRange(ObservationsClientContractTest.java:57) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:566) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at au.com.dius.pact.consumer.junit.BaseProviderRule.lambda$runPactTest$2(BaseProviderRule.java:165) at au.com.dius.pact.consumer.BaseMockServer.runAndWritePact(MockHttpServer.kt:110) at au.com.dius.pact.consumer.ConsumerPactRunnerKt.runConsumerTest(ConsumerPactRunner.kt:13) at au.com.dius.pact.consumer.junit.BaseProviderRule.runPactTest(BaseProviderRule.java:163) at au.com.dius.pact.consumer.junit.BaseProviderRule.access$100(BaseProviderRule.java:27) at au.com.dius.pact.consumer.junit.BaseProviderRule$1.evaluate(BaseProviderRule.java:83) ... 15 more Caused by: java.net.ConnectException: Connection refused (Connection refused) at java.base/java.net.PlainSocketImpl.socketConnect(Native Method) at java.base/java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:399) at java.base/java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:242) at java.base/java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:224) at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:403) at java.base/java.net.Socket.connect(Socket.java:609) at okhttp3.internal.platform.Platform.connectSocket(Platform.java:130) at okhttp3.internal.connection.RealConnection.connectSocket(RealConnection.java:263) ... 49 more

Thorn1089 commented 4 years ago

Downgrading to the 4.0.5 release of the library resolves the hang. (4.0.6 has a NoSuchMethodError related to the Gson library).

broeser commented 4 years ago

Hi @TomRK1089 , I also just figured that out, you will need GSon (com.google.code.gson) in version 2.8.6

Thorn1089 commented 4 years ago

@broeser to clarify, it sounds like patching the Gson dependency would resolve the issue with 4.0.6's NoSuchMethodError but not the larger connection hang.

uglyog commented 4 years ago

@TomRK1089 Can you provide a list of dependencies for your project? You can do this with the Maven dependency tree plugin.

I have reviewed all the changes from 4.0.5 to 4.0.6, and the main one is Groovy was changed from 2.5.x to 3.0.0. But I don't see why this should impact things. Do you use Groovy anywhere?