Using Pact JS to test both my consumers and providers. I’m successfully able to generate a pact file, and I’d like to verify those against my provider.
I have a few questions with regards to testing the provider:
- Do I need to start my provider service before I can do the tests? Should I be hitting the actual provider endpoint in the test? For example, say I have a GET /dogs endpoint on my provider code base. When I run my tests, do I need to start up my service locally, hit the /dogs endpoint and then verify the response returned for the endpoint with the pact file?
- If I want to run this as a part of my CI pipeline (I’m using CircleCI), what are some of the best practices to follow? Do I need to start up my service from the circleci build step, point to some database somewhere and then follow the steps above?
- Are there any concepts of using stubs on provider testing? If so, how do these work for staring a provider service. Is there any examples or sample code for this?
Yes, you start up your provider, and use the actual endpoint (see below for a caveat)
Sort of. Pact's mock consumer will do the hitting of the endpoint and comparing the results with the expected response in the pact file for you.
This is kind of a general question, but you would usually create a build step that starts the service, runs Pact's verification, and then tears down the service. See the end of the post for a link to an example.
So, pact is a contract testing tool. Contract testing has some important differences from functional testing.
Broadly, contract testing is about verifying that the shape of the data that you're sending and receiving is agreed upon and can be understood by both parties. It's not about verifying that the data behaves correctly. Say I have the following design for an API that takes a string representing a phone number:
+
or00
+
anywhere other than the startEven though there are a lot of cases there, it's appropriate for Pact to only have a success and a fail case:
(unless the API returns different responses for different types of fails, of course).
The contract is about what can be expressed, rather than why it is expressed.
This tells us where we can use stubs - your API endpoint workflow might look something like this, in pseudo code:
Because we're only interested in the contract, it's appropriate to stub out the business logic in
recordPhoneNumber()
, meaning that pact will test your network layer and your marshallers.Depending on your code design, the best place to put that stub will change. In our example, the stub could look something like this:
Ideally, contract testing won't need any of your infrastructure beyond the endpoint (databases, caches, etc). So, ideally, you can put your stub in a place where you won't need to fire up those things.
Pact is not a good fit for an integration testing tool (although it is possible to use it that way, you'll have other problems if you do).
You can achieve this with provider states. Here's a real example from the javascript provider example:
Yes. Check out this javascript provider example