I created 2 identical consumer pact tests each consuming the same service of a provider. When I run provider contract test, one consumer pact passes but the other gets this error:
Verifying a pact between Mobil Mudurluk Fatura Ekibi and fatura-service
Notices:
1) The pact at https://akbank.pactflow.io/pacts/provider/fatura-service/consumer/Mobil%20Mudurluk%20Fatura%20Ekibi/pact-version/11db7c322203ff8268a066c29856c81a5ede1f2b is being verified because the pact content belongs to the consumer version matching the following criterion:
* latest version of Mobil Mudurluk Fatura Ekibi that has a pact with fatura-service (0.0.1-SNAPSHOT)
2) This pact has previously been successfully verified by fatura-service. If this verification fails, it will fail the build. Read more at https://docs.pact.io/go/pending
[from Pact Broker https://akbank.pactflow.io/pacts/provider/fatura-service/consumer/Mobil%20Mudurluk%20Fatura%20Ekibi/pact-version/11db7c322203ff8268a066c29856c81a5ede1f2b/metadata/c1tdW2xdPXRydWUmc1tdW2N2XT0xMyZwPWZhbHNl]
Given Odenecek fatura varken
fatura ode
2023-04-13 12:19:01.724 INFO 7904 --- [ main] a.c.d.p.provider.junit.RunStateChanges : Invoking state change method 'Odenecek fatura varken':SETUP
fatura varken!
2023-04-13 12:19:01.852 INFO 7904 --- [o-auto-1-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring FrameworkServlet 'dispatcherServlet'
2023-04-13 12:19:01.852 INFO 7904 --- [o-auto-1-exec-1] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization started
2023-04-13 12:19:01.909 INFO 7904 --- [o-auto-1-exec-1] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization completed in 57 ms
returns a response which
has status code 200 (OK)
has a matching body (OK)
2023-04-13 12:19:02.238 WARN 7904 --- [ main] a.c.d.p.p.DefaultTestResultAccumulator : Not all of the 2 were verified. The following were missing:
2023-04-13 12:19:02.240 WARN 7904 --- [ main] a.c.d.p.p.DefaultTestResultAccumulator : fatura ode
Verifying a pact between Mobil Mudurluk Fatura Ekibi and fatura-service
Notices:
1) The pact at https://akbank.pactflow.io/pacts/provider/fatura-service/consumer/Mobil%20Mudurluk%20Fatura%20Ekibi/pact-version/11db7c322203ff8268a066c29856c81a5ede1f2b is being verified because the pact content belongs to the consumer version matching the following criterion:
* latest version of Mobil Mudurluk Fatura Ekibi that has a pact with fatura-service (0.0.1-SNAPSHOT)
2) This pact has previously been successfully verified by fatura-service. If this verification fails, it will fail the build. Read more at https://docs.pact.io/go/pending
[from Pact Broker https://akbank.pactflow.io/pacts/provider/fatura-service/consumer/Mobil%20Mudurluk%20Fatura%20Ekibi/pact-version/11db7c322203ff8268a066c29856c81a5ede1f2b/metadata/c1tdW2xdPXRydWUmc1tdW2N2XT0xMyZwPWZhbHNl]
Given Odenecek fatura yokken
fatura ode
2023-04-13 12:19:02.250 INFO 7904 --- [ main] a.c.d.p.provider.junit.RunStateChanges : Invoking state change method 'Odenecek fatura yokken':SETUP
fatura yokken!
returns a response which
has status code 404 (OK)
has a matching body (OK)
2023-04-13 12:19:02.276 WARN 7904 --- [ main] a.c.dius.pact.provider.ProviderVersion : Provider version not set, defaulting to '0.0.0'
2023-04-13 12:19:20.661 INFO 7904 --- [ main] a.c.d.p.p.DefaultVerificationReporter : Published verification result of 'Ok(interactionIds=[08597461c88e99a1d46af777ef89ee0f97e56e2e, 3108b9b44f52f56493f7ca150723bd45151dc081])' for consumer 'Consumer(name=Mobil Mudurluk Fatura Ekibi)'
Verifying a pact between Mobil Mudurluk Kampanya Ekibi and fatura-service [PENDING]
Notices:
1) The pact at https://akbank.pactflow.io/pacts/provider/fatura-service/consumer/Mobil%20Mudurluk%20Kampanya%20Ekibi/pact-version/11db7c322203ff8268a066c29856c81a5ede1f2b is being verified because the pact content belongs to the consumer version matching the following criterion:
* latest version of Mobil Mudurluk Kampanya Ekibi that has a pact with fatura-service (0.0.1-SNAPSHOT)
2) This pact is in pending state for this version of fatura-service because a successful verification result for fatura-service has not yet been published. If this verification fails, it will not cause the overall build to fail. Read more at https://docs.pact.io/go/pending
[from Pact Broker https://akbank.pactflow.io/pacts/provider/fatura-service/consumer/Mobil%20Mudurluk%20Kampanya%20Ekibi/pact-version/11db7c322203ff8268a066c29856c81a5ede1f2b/metadata/c1tdW2xdPXRydWUmc1tdW2N2XT0xNiZwPXRydWU]
Given Odenecek fatura varken
fatura ode
2023-04-13 12:19:20.675 INFO 7904 --- [ main] a.c.d.p.provider.junit.RunStateChanges : Invoking state change method 'Odenecek fatura varken':SETUP
fatura varken!
returns a response which
has status code 200 (FAILED)
includes headers
"Content-Type" with value "application/json;charset=UTF-8" (FAILED)
has a matching body (FAILED)
Pending Failures:
1) fatura ode: has status code 200
1.1) status: expected status of 200 but was 404
1.2) header: Expected a header 'Content-Type' but was missing
1.3) body-content-type: Expected a response type of 'application/json' but the actual type was 'null'
2023-04-13 12:19:20.726 WARN 7904 --- [ main] a.c.d.p.p.DefaultTestResultAccumulator : Not all of the 2 were verified. The following were missing:
2023-04-13 12:19:20.726 WARN 7904 --- [ main] a.c.d.p.p.DefaultTestResultAccumulator : fatura ode
Verifying a pact between Mobil Mudurluk Kampanya Ekibi and fatura-service [PENDING]
Notices:
1) The pact at https://akbank.pactflow.io/pacts/provider/fatura-service/consumer/Mobil%20Mudurluk%20Kampanya%20Ekibi/pact-version/11db7c322203ff8268a066c29856c81a5ede1f2b is being verified because the pact content belongs to the consumer version matching the following criterion:
* latest version of Mobil Mudurluk Kampanya Ekibi that has a pact with fatura-service (0.0.1-SNAPSHOT)
2) This pact is in pending state for this version of fatura-service because a successful verification result for fatura-service has not yet been published. If this verification fails, it will not cause the overall build to fail. Read more at https://docs.pact.io/go/pending
[from Pact Broker https://akbank.pactflow.io/pacts/provider/fatura-service/consumer/Mobil%20Mudurluk%20Kampanya%20Ekibi/pact-version/11db7c322203ff8268a066c29856c81a5ede1f2b/metadata/c1tdW2xdPXRydWUmc1tdW2N2XT0xNiZwPXRydWU]
Given Odenecek fatura yokken
fatura ode
2023-04-13 12:19:20.733 INFO 7904 --- [ main] a.c.d.p.provider.junit.RunStateChanges : Invoking state change method 'Odenecek fatura yokken':SETUP
fatura yokken!
returns a response which
has status code 404 (OK)
has a matching body (OK)
2023-04-13 12:19:20.758 WARN 7904 --- [ main] a.c.dius.pact.provider.ProviderVersion : Provider version not set, defaulting to '0.0.0'
2023-04-13 12:19:32.669 INFO 7904 --- [ main] a.c.d.p.p.DefaultVerificationReporter : Published verification result of 'Failed(results=[{interactionId=3108b9b44f52f56493f7ca150723bd45151dc081, exception=java.lang.AssertionError:
Pending Failures:
1) fatura ode: has status code 200
1.1) status: expected status of 200 but was 404
1.2) header: Expected a header 'Content-Type' but was missing
1.3) body-content-type: Expected a response type of 'application/json' but the actual type was 'null'
, description=Request to provider failed with an exception}], description=Request to provider failed with an exception)' for consumer 'Consumer(name=Mobil Mudurluk Kampanya Ekibi)'
2023-04-13 12:19:32.672 INFO 7904 --- [ Thread-2] ationConfigEmbeddedWebApplicationContext : Closing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@39a8312f: startup date [Thu Apr 13 12:18:29 EET 2023]; root of context hierarchy
2023-04-13 12:19:32.678 INFO 7904 --- [ Thread-2] o.s.c.support.DefaultLifecycleProcessor : Stopping beans in phase 0
2023-04-13 12:19:32.680 INFO 7904 --- [ Thread-2] o.s.i.endpoint.EventDrivenConsumer : Removing {logging-channel-adapter:_org.springframework.integration.errorLogger} as a subscriber to the 'errorChannel' channel
2023-04-13 12:19:32.680 INFO 7904 --- [ Thread-2] o.s.i.channel.PublishSubscribeChannel : Channel 'application:0.errorChannel' has 0 subscriber(s).
2023-04-13 12:19:32.680 INFO 7904 --- [ Thread-2] o.s.i.endpoint.EventDrivenConsumer : stopped _org.springframework.integration.errorLogger
2023-04-13 12:19:32.680 INFO 7904 --- [ Thread-2] o.s.s.c.ThreadPoolTaskScheduler : Shutting down ExecutorService 'taskScheduler'
Both consumer pact tests are identical except for consumer name. Here is the one working ok:
@RunWith(SpringRunner.class)
@SpringBootTest(
webEnvironment = SpringBootTest.WebEnvironment.NONE,
properties = "fatura-service.base-url:http://localhost:8081", //In our real setup we obviously don’t use port 8080 for the mocked server because we want to run tests in a CI environment where this port might be in use.
classes = FaturaOdemeSpringBootClient.class)
public class FaturaOdemeContractTest
{
//pact adında kullanılıyor.
@Rule
public PactProviderRule provider = new PactProviderRule("fatura-service", null, 8081, this);
@Autowired
private FaturaOdemeClient client;
@Pact(consumer = "Mobil Mudurluk Fatura Ekibi") //pact adında kullanılıyor.
public RequestResponsePact pactFaturaOdeme(PactDslWithProvider builder) {
return builder
.given("Odenecek fatura varken")
.uponReceiving("fatura ode")
.path("/fatura_ode")
.method("GET")
.query("mbb=123456&kurum=IGDAS&sonOdemeTarihi=2022-10-31")
.willRespondWith()
.status(200)
.body(
new PactDslJsonBody()
.stringType("mbb", "123456")
.integerType("faturaTutari", 10)
.integerType("komisyon", 1)
)
.toPact();
}
@PactVerification(fragment = "pactFaturaOdeme") //yukarıdaki metod adıyla aynı olması gerekiyor sanırım.
@Test
public void testFaturaOdeme() {
FaturaOdemeSonucu faturaOdemeSonucu = client.faturaOde("123456", "IGDAS", Date.valueOf("2022-10-31"));
FaturaOdemeSonucu expected = new FaturaOdemeSonucu("123456", 10,1);
Assert.assertEquals(
expected,
faturaOdemeSonucu);
}
@Pact(consumer = "Mobil Mudurluk Fatura Ekibi") //pact adında kullanılıyor.
public RequestResponsePact pactFaturaYok(PactDslWithProvider builder) {
return builder
.given("Odenecek fatura yokken")
.uponReceiving("fatura ode")
.path("/fatura_ode")
.method("GET")
.query("mbb=123456&kurum=IGDAS&sonOdemeTarihi=2022-10-31")
.willRespondWith()
.status(404)
.toPact();
}
@PactVerification(fragment = "pactFaturaYok") //yukarıdaki metod adıyla aynı olması gerekiyor sanırım.
@Test
public void testFaturaYok() {
try {
client.faturaOde("123456", "IGDAS", Date.valueOf("2022-10-31"));
Assert.fail("Servis 404 dönmedi!");
} catch (HttpClientErrorException e) {
Assert.assertTrue(e.getMessage().contains("404"));
}
}
}
And the one causing the error:
@RunWith(SpringRunner.class)
@SpringBootTest(
webEnvironment = SpringBootTest.WebEnvironment.NONE,
properties = "fatura-service.base-url:http://localhost:8081", //In our real setup we obviously don’t use port 8080 for the mocked server because we want to run tests in a CI environment where this port might be in use.
classes = FaturaOdemeSpringBootClient.class)
public class FaturaOdemeContractTest
{
//pact adında kullanılıyor.
@Rule
public PactProviderRule provider = new PactProviderRule("fatura-service", null, 8081, this);
@Autowired
private FaturaOdemeClient client;
@Pact(consumer = "Mobil Mudurluk Kampanya Ekibi") //pact adında kullanılıyor.
public RequestResponsePact pactFaturaOdeme(PactDslWithProvider builder) {
return builder
.given("Odenecek fatura varken")
.uponReceiving("fatura ode")
.path("/fatura_ode")
.method("GET")
.query("mbb=123456&kurum=IGDAS&sonOdemeTarihi=2022-10-31")
.willRespondWith()
.status(200)
.body(
new PactDslJsonBody()
.stringType("mbb", "123456")
.integerType("faturaTutari", 10)
.integerType("komisyon", 1)
)
.toPact();
}
@PactVerification(fragment = "pactFaturaOdeme") //yukarıdaki metod adıyla aynı olması gerekiyor sanırım.
@Test
public void testFaturaOdeme() {
FaturaOdemeSonucu faturaOdemeSonucu = client.faturaOde("123456", "IGDAS", Date.valueOf("2022-10-31"));
FaturaOdemeSonucu expected = new FaturaOdemeSonucu("123456", 10,1);
Assert.assertEquals(
expected,
faturaOdemeSonucu);
}
@Pact(consumer = "Mobil Mudurluk Kampanya Ekibi") //pact adında kullanılıyor.
public RequestResponsePact pactFaturaYok(PactDslWithProvider builder) {
return builder
.given("Odenecek fatura yokken")
.uponReceiving("fatura ode")
.path("/fatura_ode")
.method("GET")
.query("mbb=123456&kurum=IGDAS&sonOdemeTarihi=2022-10-31")
.willRespondWith()
.status(404)
.toPact();
}
@PactVerification(fragment = "pactFaturaYok") //yukarıdaki metod adıyla aynı olması gerekiyor sanırım.
@Test
public void testFaturaYok() {
try {
client.faturaOde("123456", "IGDAS", Date.valueOf("2022-10-31"));
Assert.fail("Servis 404 dönmedi!");
} catch (HttpClientErrorException e) {
Assert.assertTrue(e.getMessage().contains("404"));
}
}
}
If relevant, here is the provider contract test:
@RunWith(SpringRestPactRunner.class)
@Provider("fatura-service")
@PactBroker(
url="https://akbank.pactflow.io",
authentication=@PactBrokerAuth(token="MyToken")) //TODO Koda gömülü olmamalı.
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class FaturaOdemeContractTest {
@TestTarget
public final Target target = new SpringBootHttpTarget();
@State("Odenecek fatura varken")
public void faturaVarken() {
System.out.println("fatura varken!");
}
@State("Odenecek fatura yokken")
public void faturaYokken() {
System.out.println("fatura yokken!");
FaturaOdemeMockServis mockServis = (FaturaOdemeMockServis) ContractTestConfiguration.getFaturaOdemeRestServis();
mockServis.setFaturaVar(false);
}
}
Here I'm trying to see what happens when 2 consumers have very similar usages for the same provider and provider tells them to use the same contract to make the things easier. Please advise if this is wrong and each consumer should describe what it wants of the service from their perspectives.