python-3.xpactpact-python

Actual interactions do not match expected interactions for mock MockService


I'm new to both python and contract testing. I'm trying to test my consumer application using pact-python.

This is the test file test_posts_controller.py

import unittest
import atexit
from pact import Consumer, Provider, Term
import requests

pact = Consumer('Consumer').has_pact_with(Provider('Provider'))
pact.start_service()
atexit.register(pact.stop_service)

class GetPostsContract(unittest.TestCase):
    def test_get_all_posts(self):
        expected = {
            "userId": 1,
            "id": 1,
            "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
            "body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
        }

        (pact
            .given('posts exist')
            .upon_receiving('a request for post by id')
            .with_request('GET', '/posts/1')
            .will_respond_with(200, body=expected))

        with pact: 
            result = requests.get('https://jsonplaceholder.typicode.com/posts/1')

        self.assertEqual(result.json(), expected)

Here I'm trying to hit JSONPlaceholder.

I'm using pytest command to run the test.

But I'm getting the below error. I don't know what i'm missing.

self = <pact.pact.Pact object at 0x10cc8c8d0>

def verify(self):
    """
    Have the mock service verify all interactions occurred.

    Calls the mock service to verify that all interactions occurred as
    expected, and has it write out the contracts to disk.

    :raises AssertionError: When not all interactions are found.
    """
    self._interactions = []
    resp = requests.get(
        self.uri + '/interactions/verification',
        headers=self.HEADERS)
    >       assert resp.status_code == 200, resp.text
    E       AssertionError: Actual interactions do not match expected interactions for mock MockService.
    E
    E       Missing requests:
    E           GET /posts/1
    E
    E       See pact-mock-service.log for details.

    venv/lib/python3.7/site-packages/pact/pact.py:209: AssertionError

I have tried pact.setup() and pact.verify() also but still I'm getting the same error. Can someone help me fix this?

And it doesn't create pactfile also. What are the things I have to setup?.


Solution

  • How to find out why it's happening

    AssertionError: Actual interactions do not match expected interactions for mock MockService.

    ^ This error says that the pact mock didn't receive the interactions that were described in the Pact test.

    E       Missing requests:
    E           GET /posts/1
    

    ^ This part says that the mock didn't receive a GET request for /posts/1. If the mock server had received other requests (eg a POST that it wasn't expecting), they would also be listed here.

    So, we know that no requests hit the mock server during the test.

    Reading the rest of the test class, we have:

        with pact: 
            result = requests.get('https://jsonplaceholder.typicode.com/posts/1')
    

    This shows that the test is hitting jsonplaceholder.typicode.com instead of the mock set up during the test. So, the error is correct - to fix it we need to hit the mock server:

    How to fix it

    To fix your case, you'll need to contact the pact mock server instead:

        with pact: 
            result = requests.get('https://localhost:1234/posts/1') 
    

    (Or whatever port you have configured Pact to listen on).

    You can also get this directly from Pact:

        with pact: 
            result = requests.get(pact.uri + '/posts/1') 
    

    How to learn more

    You might find this diagram of a consumer test useful (taken from the How Pact Works section of the Pact documentation):

    Consumer test

    Your consumer code is the orange part, and the blue part is the mock provided by Pact.

    During a Pact test, the consumer doesn't contact the actual provider, it only contacts the mock provider. The reverse is true for a provider verification - only the mock consumer contacts the real provider.

    This means you don't need to spin up the consumer and provider together in order to test. This advantage is a major selling point of contract testing.