mockallan


Namemockallan JSON
Version 0.1.1 PyPI version JSON
download
home_pagehttps://github.com/david-domz/mockallan
SummaryLightweight HTTP server mock for CI and testing environments.
upload_time2024-11-17 18:32:22
maintainerNone
docs_urlNone
authorDavid Domínguez
requires_python<4,>=3.8
licenseMIT
keywords python http rest mock test pytest
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            ![image](mockallan.png)

[![PyPI package version](https://badge.fury.io/py/mockallan.svg)](https://pypi.org/project/mockallan/) [![Supported Python versions](https://img.shields.io/pypi/pyversions/mockallan.svg)](https://pypi.org/project/mockallan/) [![Python package](https://github.com/david-domz/mockallan/actions/workflows/python-package.yml/badge.svg)](https://github.com/david-domz/mockallan/actions/workflows/python-package.yml) [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=david-domz_mockallan&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=david-domz_mockallan)

Mockallan is a lightweight HTTP server mock for CI and test environments.


## Highlights

- Command line interface for CI and test environments.

- Configurable default and per endpoint responses.

- Robust assertion capabilities.

- Request body matching in assertions based on
  - Text matching
  - JSON message matching
  - JSON schema validation
  - XML schema validation
  - Regular expression matching

- Concise codebase.

- API naming inspired by the `Mock` class from the standard Python `unittest.mock` library.

## Requirements

- Python >= 3.8

## Installation

Mockallan is available on [PyPI](https://pypi.org/project/mockallan/). Install it using pip.

```bash
pip install mockallan
```

Creating and activating a virtual environment first is recommended. Alternatively, see [mockallan-docker](https://github.com/david-domz/mockallan-docker) repository to run Mockallan in a docker container. 

## Getting Started


1) Run `mockallan.py`

```bash
python mockallan.py
Listening on 0.0.0.0:8080
```

2) Run the system under test.

You can use `curl` to simulate a request performed by the system under test. For example, if we expect our system under test to perform a `POST /orders/order_e2b9/products`, we would run the following `curl` command.

```bash
curl -s -X POST http://localhost:8080/orders/order_e2b9/products --data '{
	"product_id": "foo",
	"description": "bar",
	"amount": 1
}'
```

Mockallan will reply with the factory default response.

```json
{
	"status": "200",
	"message": "This is mockallan's factory default response."
}
```

3) Make assertions on the expected request.

```bash
curl -X GET "http://localhost:8080/assert-called?method=POST&path=/orders/order_e2b9/products"
```

If the assertion request returns 200 then everything went well.

```json
{
	"status": 200,
	"type": "assertion-success",
	"title": "Assertion request GET /assert-called succeeded",
	"detail": "POST /orders/order_e2b9/products called 1 times."
}
```

If it returns 409 then the assertion failed and the system under test did not behave as expected.

```json
{
	"status": 409,
	"type": "assertion-error",
	"title": "Assertion request GET /assert-called failed",
	"detail": "Expected POST /orders/order_e2b9/products to be called 1 times. Called 0 times."
}
```

## Using Configurable Stub Responses

1) Create a stub configuration JSON file or use the `stub_config.json` provided in this repository.

E.g.
```json
{
	"endpoints": [
		{
			"request": {
				"method": "POST",
				"path": "/orders/order_e2b9/products"
			},
			"response": {
				"status_code": 200,
				"headers": {
					"Content-type": "application/json"
				},
				"body": {
					"status": "200",
					"message": "This is the configured response for POST /orders/order_e2b9/products"
				}
			}
		}
	]
}
```

2) Run `mockallan.py` and provide the JSON file.

```bash
python mockallan.py -c stub_config.json
```

3) Run the system under test or simulate the request performed by it. The mock will reply with the configured response for `POST /orders/order_e2b9/products`.

4) Make assertions on the expected request.

```bash
curl -X GET "http://localhost:8080/assert-called?method=POST&path=/orders/order_e2b9/products"
```

If the assertion request returns 200 then everything went fine. If it returns 409 then the assertion failed and the system under test did not behave as expected.


## Using `/assert-called-with` And `/assert-called-once-with`

Let's explore additional validation options using the `POST /assert-called-with` and `POST /assert-called-once-with` endpoints. The body message provided in these requests corresponds to a
- Text message
- JSON message
- JSON schema
- XML schema
- or a regular expression string

to match as shown in the following sections.


### JSON Schema Validation Assertions

Add `Content-Type: application/schema+json` to the `POST /assert-called-with` or `POST /assert-called-once-with` request and place the JSON schema message in the body.

E.g. 

```bash
curl -X POST --header 'Content-Type: application/json+schema'	\
	"http://localhost:8080/assert-called-with?method=POST&path=/orders/order_e2b9/products"	\
	--data '{
		"$schema": "http://json-schema.org/draft-07/schema#",
		"type": "object",
		"properties": {
			"orderNumber": {
				"type": "string"
			},
			"products": {
				"type": "array",
				"items": {
					"type": "object",
					"properties": {
						"productId": {
							"type": "string"
						},
						"quantity": {
							"type": "integer",
							"minimum": 1
						}
					},
					"required": ["productId", "quantity"]
				}
			}
		},
		"required": ["orderNumber", "products"]
	}'
```

### XML Schema Validation Assertions

Add `Content-Type: application/xml` to the `POST /assert-called-with` or `POST /assert-called-once-with` request and place the XML schema message in the body.

E.g.

```bash
curl -X POST --header 'Content-Type: application/xml'	\
	"http://localhost:8080/assert-called-with?method=POST&path=/orders/order_e2b9/products"	\
	--data '<?xml version="1.0" encoding="UTF-8"?>
    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
        <xs:element name="order">
            <xs:complexType>
                <xs:sequence>
                    <xs:element name="orderNumber" type="xs:string"/>
                    <xs:element name="products" type="productListType"/>
                </xs:sequence>
            </xs:complexType>
        </xs:element>
        <xs:complexType name="productListType">
            <xs:sequence>
                <xs:element name="product" type="productType" minOccurs="0" maxOccurs="unbounded"/>
            </xs:sequence>
        </xs:complexType>
        <xs:complexType name="productType">
            <xs:sequence>
                <xs:element name="productId" type="xs:string"/>
                <xs:element name="quantity" type="xs:integer"/>
            </xs:sequence>
        </xs:complexType>
    </xs:schema>'
```

### Regex Validation Assertions

Add the custom header `X-Mockallan-Validator: regex` to the `POST /assert-called-with` or `POST /assert-called-once-with` request and place the regular expression in the body. 

E.g.

```bash
curl -X POST --header 'X-Mockallan-Validator: regex'	\
	"http://localhost:8080/assert-called-with?method=POST&path=/orders/order_e2b9/products"	\
	--data '{"orderNumber":"\w+","products":\[\{"productId":"\w+","quantity":\d+}(,\{"productId":"\w+","quantity":\d+\})*\]}'
```

<!-- ## Stub Configuration JSON

The Stub Configuration JSON format configures mockallan responses.

### Stub Configuration Example


```json
{
	"defaults": {
		"response": {
			"status_code": 200,
			"headers": {
				"Content-Type": "application/json"
			},
			"body": {
				"status": 200,
				"message": "This is the default response configured in stub_config.json"
			}
		}
	},
	"endpoints": [
		{
			"request": {
				"method": "GET"
				"path": "/orders/order_e2b9/products"
			},
			"response": {
				"status_code": 200
				"headers": {
					"Content-type": "application/json"
				},
				"body": {
					"status": 200,
					"message": "This is the configured response for GET /orders/order_e2b9/products"
				}
			}
		}
	]
}
``` -->

## Stub Configuration API

The Stub Configuration API allows the test client to configure the mock at runtime.

|Method|Path|Query Params|Request Body|Status|Response Body|
|-|-|-|-|-|-|
|PUT|/configure|-|JSON stub configuration|204; 400|-|
|GET|/configure|-|-|200|JSON stub configuration|


## Assertion API

The Assertion API allows for the validation of expected requests.

|Method|Path|Query Params|Request Body|Status|Response Body|
|-|-|-|-|-|-|
|GET|/assert-called|method, path|-|200 OK; 400; 409|Assertion success or error message|
|GET|/assert-called-once|method, path|-|200 OK; 400; 409|Assertion success or error message|
|POST|/assert-called-with|method, path|JSON object, JSON schema, XML schema or regex|200 OK; 400; 409|Assertion success or error message|
|POST|/assert-called-once-with|method, path|JSON object, JSON schema, XML schema, regex or message body|200 OK; 400; 409|Assertion success or error message|
|GET|/request-body|-|-|200 OK; 409|The request body that the mock was last called with|
|GET|/request-body-list|-|-|200 OK|List of all the requests made to the mock in sequence|
|GET|/request-count|-|-|200 OK|Request count|



## Contributing

Please submit feedback, ideas and bug reports by [creating a new issue](https://github.com/david-domz/mockallan/issues).


## License

This project is licensed under the terms of the MIT license.


## Related Projects

- [mockallan-docker](https://github.com/david-domz/mockallan-docker) - Containerized lightweight HTTP server mock.
- [mockallan-python-client](https://github.com/david-domz/mockallan-python-client) - Mockallan python client class.



            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/david-domz/mockallan",
    "name": "mockallan",
    "maintainer": null,
    "docs_url": null,
    "requires_python": "<4,>=3.8",
    "maintainer_email": null,
    "keywords": "python, http, REST, mock, test, pytest",
    "author": "David Dom\u00ednguez",
    "author_email": "david.7b8@gmail.com",
    "download_url": null,
    "platform": null,
    "description": "![image](mockallan.png)\n\n[![PyPI package version](https://badge.fury.io/py/mockallan.svg)](https://pypi.org/project/mockallan/) [![Supported Python versions](https://img.shields.io/pypi/pyversions/mockallan.svg)](https://pypi.org/project/mockallan/) [![Python package](https://github.com/david-domz/mockallan/actions/workflows/python-package.yml/badge.svg)](https://github.com/david-domz/mockallan/actions/workflows/python-package.yml) [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=david-domz_mockallan&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=david-domz_mockallan)\n\nMockallan is a lightweight HTTP server mock for CI and test environments.\n\n\n## Highlights\n\n- Command line interface for CI and test environments.\n\n- Configurable default and per endpoint responses.\n\n- Robust assertion capabilities.\n\n- Request body matching in assertions based on\n  - Text matching\n  - JSON message matching\n  - JSON schema validation\n  - XML schema validation\n  - Regular expression matching\n\n- Concise codebase.\n\n- API naming inspired by the `Mock` class from the standard Python `unittest.mock` library.\n\n## Requirements\n\n- Python >= 3.8\n\n## Installation\n\nMockallan is available on [PyPI](https://pypi.org/project/mockallan/). Install it using pip.\n\n```bash\npip install mockallan\n```\n\nCreating and activating a virtual environment first is recommended. Alternatively, see [mockallan-docker](https://github.com/david-domz/mockallan-docker) repository to run Mockallan in a docker container. \n\n## Getting Started\n\n\n1) Run `mockallan.py`\n\n```bash\npython mockallan.py\nListening on 0.0.0.0:8080\n```\n\n2) Run the system under test.\n\nYou can use `curl` to simulate a request performed by the system under test. For example, if we expect our system under test to perform a `POST /orders/order_e2b9/products`, we would run the following `curl` command.\n\n```bash\ncurl -s -X POST http://localhost:8080/orders/order_e2b9/products --data '{\n\t\"product_id\": \"foo\",\n\t\"description\": \"bar\",\n\t\"amount\": 1\n}'\n```\n\nMockallan will reply with the factory default response.\n\n```json\n{\n\t\"status\": \"200\",\n\t\"message\": \"This is mockallan's factory default response.\"\n}\n```\n\n3) Make assertions on the expected request.\n\n```bash\ncurl -X GET \"http://localhost:8080/assert-called?method=POST&path=/orders/order_e2b9/products\"\n```\n\nIf the assertion request returns 200 then everything went well.\n\n```json\n{\n\t\"status\": 200,\n\t\"type\": \"assertion-success\",\n\t\"title\": \"Assertion request GET /assert-called succeeded\",\n\t\"detail\": \"POST /orders/order_e2b9/products called 1 times.\"\n}\n```\n\nIf it returns 409 then the assertion failed and the system under test did not behave as expected.\n\n```json\n{\n\t\"status\": 409,\n\t\"type\": \"assertion-error\",\n\t\"title\": \"Assertion request GET /assert-called failed\",\n\t\"detail\": \"Expected POST /orders/order_e2b9/products to be called 1 times. Called 0 times.\"\n}\n```\n\n## Using Configurable Stub Responses\n\n1) Create a stub configuration JSON file or use the `stub_config.json` provided in this repository.\n\nE.g.\n```json\n{\n\t\"endpoints\": [\n\t\t{\n\t\t\t\"request\": {\n\t\t\t\t\"method\": \"POST\",\n\t\t\t\t\"path\": \"/orders/order_e2b9/products\"\n\t\t\t},\n\t\t\t\"response\": {\n\t\t\t\t\"status_code\": 200,\n\t\t\t\t\"headers\": {\n\t\t\t\t\t\"Content-type\": \"application/json\"\n\t\t\t\t},\n\t\t\t\t\"body\": {\n\t\t\t\t\t\"status\": \"200\",\n\t\t\t\t\t\"message\": \"This is the configured response for POST /orders/order_e2b9/products\"\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t]\n}\n```\n\n2) Run `mockallan.py` and provide the JSON file.\n\n```bash\npython mockallan.py -c stub_config.json\n```\n\n3) Run the system under test or simulate the request performed by it. The mock will reply with the configured response for `POST /orders/order_e2b9/products`.\n\n4) Make assertions on the expected request.\n\n```bash\ncurl -X GET \"http://localhost:8080/assert-called?method=POST&path=/orders/order_e2b9/products\"\n```\n\nIf the assertion request returns 200 then everything went fine. If it returns 409 then the assertion failed and the system under test did not behave as expected.\n\n\n## Using `/assert-called-with` And `/assert-called-once-with`\n\nLet's explore additional validation options using the `POST /assert-called-with` and `POST /assert-called-once-with` endpoints. The body message provided in these requests corresponds to a\n- Text message\n- JSON message\n- JSON schema\n- XML schema\n- or a regular expression string\n\nto match as shown in the following sections.\n\n\n### JSON Schema Validation Assertions\n\nAdd `Content-Type: application/schema+json` to the `POST /assert-called-with` or `POST /assert-called-once-with` request and place the JSON schema message in the body.\n\nE.g. \n\n```bash\ncurl -X POST --header 'Content-Type: application/json+schema'\t\\\n\t\"http://localhost:8080/assert-called-with?method=POST&path=/orders/order_e2b9/products\"\t\\\n\t--data '{\n\t\t\"$schema\": \"http://json-schema.org/draft-07/schema#\",\n\t\t\"type\": \"object\",\n\t\t\"properties\": {\n\t\t\t\"orderNumber\": {\n\t\t\t\t\"type\": \"string\"\n\t\t\t},\n\t\t\t\"products\": {\n\t\t\t\t\"type\": \"array\",\n\t\t\t\t\"items\": {\n\t\t\t\t\t\"type\": \"object\",\n\t\t\t\t\t\"properties\": {\n\t\t\t\t\t\t\"productId\": {\n\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"quantity\": {\n\t\t\t\t\t\t\t\"type\": \"integer\",\n\t\t\t\t\t\t\t\"minimum\": 1\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\t\"required\": [\"productId\", \"quantity\"]\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t\"required\": [\"orderNumber\", \"products\"]\n\t}'\n```\n\n### XML Schema Validation Assertions\n\nAdd `Content-Type: application/xml` to the `POST /assert-called-with` or `POST /assert-called-once-with` request and place the XML schema message in the body.\n\nE.g.\n\n```bash\ncurl -X POST --header 'Content-Type: application/xml'\t\\\n\t\"http://localhost:8080/assert-called-with?method=POST&path=/orders/order_e2b9/products\"\t\\\n\t--data '<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n    <xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\">\n        <xs:element name=\"order\">\n            <xs:complexType>\n                <xs:sequence>\n                    <xs:element name=\"orderNumber\" type=\"xs:string\"/>\n                    <xs:element name=\"products\" type=\"productListType\"/>\n                </xs:sequence>\n            </xs:complexType>\n        </xs:element>\n        <xs:complexType name=\"productListType\">\n            <xs:sequence>\n                <xs:element name=\"product\" type=\"productType\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n            </xs:sequence>\n        </xs:complexType>\n        <xs:complexType name=\"productType\">\n            <xs:sequence>\n                <xs:element name=\"productId\" type=\"xs:string\"/>\n                <xs:element name=\"quantity\" type=\"xs:integer\"/>\n            </xs:sequence>\n        </xs:complexType>\n    </xs:schema>'\n```\n\n### Regex Validation Assertions\n\nAdd the custom header `X-Mockallan-Validator: regex` to the `POST /assert-called-with` or `POST /assert-called-once-with` request and place the regular expression in the body. \n\nE.g.\n\n```bash\ncurl -X POST --header 'X-Mockallan-Validator: regex'\t\\\n\t\"http://localhost:8080/assert-called-with?method=POST&path=/orders/order_e2b9/products\"\t\\\n\t--data '{\"orderNumber\":\"\\w+\",\"products\":\\[\\{\"productId\":\"\\w+\",\"quantity\":\\d+}(,\\{\"productId\":\"\\w+\",\"quantity\":\\d+\\})*\\]}'\n```\n\n<!-- ## Stub Configuration JSON\n\nThe Stub Configuration JSON format configures mockallan responses.\n\n### Stub Configuration Example\n\n\n```json\n{\n\t\"defaults\": {\n\t\t\"response\": {\n\t\t\t\"status_code\": 200,\n\t\t\t\"headers\": {\n\t\t\t\t\"Content-Type\": \"application/json\"\n\t\t\t},\n\t\t\t\"body\": {\n\t\t\t\t\"status\": 200,\n\t\t\t\t\"message\": \"This is the default response configured in stub_config.json\"\n\t\t\t}\n\t\t}\n\t},\n\t\"endpoints\": [\n\t\t{\n\t\t\t\"request\": {\n\t\t\t\t\"method\": \"GET\"\n\t\t\t\t\"path\": \"/orders/order_e2b9/products\"\n\t\t\t},\n\t\t\t\"response\": {\n\t\t\t\t\"status_code\": 200\n\t\t\t\t\"headers\": {\n\t\t\t\t\t\"Content-type\": \"application/json\"\n\t\t\t\t},\n\t\t\t\t\"body\": {\n\t\t\t\t\t\"status\": 200,\n\t\t\t\t\t\"message\": \"This is the configured response for GET /orders/order_e2b9/products\"\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t]\n}\n``` -->\n\n## Stub Configuration API\n\nThe Stub Configuration API allows the test client to configure the mock at runtime.\n\n|Method|Path|Query Params|Request Body|Status|Response Body|\n|-|-|-|-|-|-|\n|PUT|/configure|-|JSON stub configuration|204; 400|-|\n|GET|/configure|-|-|200|JSON stub configuration|\n\n\n## Assertion API\n\nThe Assertion API allows for the validation of expected requests.\n\n|Method|Path|Query Params|Request Body|Status|Response Body|\n|-|-|-|-|-|-|\n|GET|/assert-called|method, path|-|200 OK; 400; 409|Assertion success or error message|\n|GET|/assert-called-once|method, path|-|200 OK; 400; 409|Assertion success or error message|\n|POST|/assert-called-with|method, path|JSON object, JSON schema, XML schema or regex|200 OK; 400; 409|Assertion success or error message|\n|POST|/assert-called-once-with|method, path|JSON object, JSON schema, XML schema, regex or message body|200 OK; 400; 409|Assertion success or error message|\n|GET|/request-body|-|-|200 OK; 409|The request body that the mock was last called with|\n|GET|/request-body-list|-|-|200 OK|List of all the requests made to the mock in sequence|\n|GET|/request-count|-|-|200 OK|Request count|\n\n\n\n## Contributing\n\nPlease submit feedback, ideas and bug reports by [creating a new issue](https://github.com/david-domz/mockallan/issues).\n\n\n## License\n\nThis project is licensed under the terms of the MIT license.\n\n\n## Related Projects\n\n- [mockallan-docker](https://github.com/david-domz/mockallan-docker) - Containerized lightweight HTTP server mock.\n- [mockallan-python-client](https://github.com/david-domz/mockallan-python-client) - Mockallan python client class.\n\n\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Lightweight HTTP server mock for CI and testing environments.",
    "version": "0.1.1",
    "project_urls": {
        "Homepage": "https://github.com/david-domz/mockallan"
    },
    "split_keywords": [
        "python",
        " http",
        " rest",
        " mock",
        " test",
        " pytest"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "5362252788a482bfcac77662ef877a2821a7a64eb190d0d5996533200bfffc55",
                "md5": "139630b2a48a96f120a4b9dd70ff7949",
                "sha256": "a5f76b21292858a110d82bd61cba1ba41baad7c770efcd4191150c753c6eb77e"
            },
            "downloads": -1,
            "filename": "mockallan-0.1.1-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "139630b2a48a96f120a4b9dd70ff7949",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": "<4,>=3.8",
            "size": 13605,
            "upload_time": "2024-11-17T18:32:22",
            "upload_time_iso_8601": "2024-11-17T18:32:22.253534Z",
            "url": "https://files.pythonhosted.org/packages/53/62/252788a482bfcac77662ef877a2821a7a64eb190d0d5996533200bfffc55/mockallan-0.1.1-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-11-17 18:32:22",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "david-domz",
    "github_project": "mockallan",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "requirements": [],
    "lcname": "mockallan"
}
        
Elapsed time: 5.02272s