DEV Community

David Dom'z
David Dom'z

Posted on

Introducing Mockallan: Testing with API-Level Stubs and Mocks

Stubs and mocks are two fundamental concepts to facilitate testing and ensure that code functions correctly.

A stub is a simplified implementation of a component that provides predetermined responses to method calls. Stubs are often used to simulate the behavior of external dependencies, such as databases or web services, by returning predefined data. They focus on providing consistent, controlled responses, allowing developers to isolate the code under test from external dependencies.

A mock, on the other hand, is more concerned with behavior verification. It tracks the interactions of the code under test with its dependencies. Mocks can be set with expectations for method calls and parameter values, and they check whether those expectations are met during the test. They help ensure that the code being tested correctly interacts with its dependencies and performs the expected actions.

For a deeper dive into mocks, stubs, and other test doubles, refer to Martin Fowler's popular article Mocks Aren't Stubs.

API-Level Stubs and Mocks

Mockallan seamlessly incorporates the concepts of stub and mock into the API domain. As an HTTP server mock, Mockallan allows developers to set up customizable HTTP responses to simulate API behavior, just like stubs provide predefined return values for method calls in unit testing.

In addition, it supports request assertions, enabling the verification of expected API requests, similar to how mocks track and verify method calls.

Let's see how Mockallan supports both stubs and mocks.

Configuring Stubs

Mockallan allows you to configure responses for specific endpoints. You can define the response status codes, headers, and response body content for different HTTP methods and paths using a JSON file.

Here's how you can stub an HTTP endpoint for a GET request.

First, create a JSON file and configure an endpoint for a GET request to the /products endpoint:

{
    "endpoints": [
        {
            "request": {
                "method": "GET",
                "path": "/products"
            },
            "response": {
                "code": 200,
                "headers": {
                    "Content-Type": "application/json"
                },
                "body": {
                    "products": [
                        {
                            "id": 1,
                            "name": "Product A"
                        },
                        {
                            "id": 2,
                            "name": "Product B"
                        }
                    ]
                }
            }
        }
    ]
}
Enter fullscreen mode Exit fullscreen mode

Start Mockallan with the stub configuration file:

python -m mockallan -c stub_config.json
Enter fullscreen mode Exit fullscreen mode

Now, you can use curl to make a GET request to the stubbed endpoint:

curl -X GET http://localhost:8080/products
Enter fullscreen mode Exit fullscreen mode

Mockallan will reply with the configured response:

{
    "products": [
        {
            "id": 1,
            "name": "Product A"
        },
        {
            "id": 2,
            "name": "Product B"
        }
    ]
}
Enter fullscreen mode Exit fullscreen mode

This enables you to simulate the behavior of external services and APIs in a controlled and predictable manner during your tests.

Mocking and Assertions

You can use Mockallan's Assertion API to validate that your software under test made the expected requests to the mock server.

Let's see an example of how to place an assertion for the request that we performed few lines above:

curl -X GET http://localhost:8080/products
Enter fullscreen mode Exit fullscreen mode

By specifying the HTTP method and path in a /assert-called request, you can ensure that your code interacts with the mock as intended. Use the following curl command to place the assertion:

curl "http://localhost:8080/assert-called?method=GET&path=/products"
Enter fullscreen mode Exit fullscreen mode

Mockallan will reply with an assertion result. If the assertion request returns a 200 status, it means the request was made as expected, and your test has succeeded.

{
    "status": 200,
    "type": "assertion-success",
    "title": "Assertion request GET /assert-called succeeded",
    "detail": "GET /products called 1 time."
}
Enter fullscreen mode Exit fullscreen mode

If the request was not made, or if there were discrepancies, the assertion will return a 409 status, indicating that the test has failed:

{
    "status": 409,
    "type": "assertion-error",
    "title": "Assertion request GET /assert-called failed",
    "detail": "Expected GET /products to be called 1 time. Called 0 times."
}
Enter fullscreen mode Exit fullscreen mode

This illustrates how Mockallan can be used to validate whether your software under test made the expected requests to the mock server, providing essential feedback and enhancing the reliability of their tests.

Mockallan also offers features like request body matching based on JSON schema validation, XML schema validation, and regular expressions, making it a versatile tool.

In summary, Mockallan provides a comprehensive solution for both stubbing and mocking, allowing you to simulate external dependencies and verify the interactions of your code with those dependencies.

References

Top comments (0)