![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"
}