Hi, I am learning the pact-jvm framework by rewrit...
# pact-jvm
k
Hi, I am learning the pact-jvm framework by rewriting some of our existing wiremock tests. I’ve noticed that in our wiremock tests, multiple services are mocked in a single test. So in pact-jvm terms, that would be a multiprovider test: https://docs.pact.io/implementation_guides/jvm/consumer/junit5#using-multiple-providers-in-a-test-425. Ive followed the instructions and I get the test running, however I’ve ran into problems when defining mock provider ports in case a multiprovider test. I assume that you have to run a different instance of mockserver for each provider, so that each provider will have their own contract. By default a random port is used for each mockserver instance launched during a test. However our application is configured to call the provider by a fixed port. In case of a single provider test, this would be resolved using “port = 1234” in the @PactTestFor annotation:
Copy code
@Test
@PactTestFor(providerName = "provider1", port = "1234")
public void example(MockServer provider1mock) {
    ...
}
However, when I do this in a multiprovider test:
Copy code
@Test
@PactTestFor(pactMethods = {"createProvider1Pact", "createProvider2Pact"}, port = "1234")
public void example(@ForProvider("provider1") MockServer provider1mock, @ForProvider("provider2") MockServer provider2mock) {
   ...
}
I get an “address already in used” exception. Which is logical since I instantiate 2 instances of mockserver, and only provide 1 port. It tries to launch both on the same port. However I have found no way of specifying which mockserver should use which port. Is there a way to do this? I could not find anything in the documentation or source code, though I am unfamiliar with kotlin, I may have missed something. I tried making a subclass of MockServer and set the port myself, but then I ran into injection/instantiation issues with my new class. Alternatively, i have also not found a way to let the application use whatever random port is chosen for the mock.
g
Hi, yeah from what I know from working with the jvm is the only way to be able to force it to use a certain port is to explicitly set the lower and upper port values. If the port the APIs use is a variable, it might be possible to override/set this value depending on what your tech stack is. So when you send request to make a provider, it response with the port number. Can use that to then set your variables. Though my experience is with the jdk 8 implementation 🙂
k
hmm I did not know you could set port lower and upper values. But I think that wont work either. If I just create a range of 2 ports: 4000-4001, then theres still no guarantee that provider 1 will always get 4000 and provider 2 will get 4001?
g
-l 4000 and -u 4000
will set it to one port. So would have to spin up the jvm 2 times with different ports in order to force it to only give you a pact provider server running on an explicit port.
k
Doesnt spinning up 2 jvms (somehow) scream “there must be or should be a better way to do this”? Is my usecase that unordinary?
g
Again, see if can adapt the code, capture the API response from the jvm when create the server. Then use that value to set the port of your solution 🫠 If application is too port dependent then I would raise this as a configuration issue. Else, suggestion above will mean you would still be able to set the ports. Otherwise make a PR I guess to make it do what you want.