Mimicker is a Python-native HTTP mocking server inspired by WireMock, designed to simplify the process of stubbing and mocking HTTP endpoints for testing purposes. Mimicker requires no third-party libraries and is lightweight, making it ideal for integration testing, local development, and CI environments.
- Create HTTP stubs for various endpoints and methods
- Mock responses with specific status codes, headers, and body content
- Flexible configuration for multiple endpoints
Mimicker can be installed directly from PyPI using pip or Poetry:
pip install mimicker
poetry add mimicker
To start Mimicker on a specific port with a simple endpoint, you can use the following code snippet:
from mimicker.mimicker import mimicker, get
mimicker(8080).routes(
get("/hello").
body({"message": "Hello, World!"}).
status(200)
)
Mimicker can handle path parameters dynamically. Here's how you can mock an endpoint with a variable in the path:
from mimicker.mimicker import mimicker, get
mimicker(8080).routes(
get("/hello/{name}")
.body({"message": "Hello, {name}!"})
.status(200)
)
# When the client sends a request to /hello/world, the response will be:
# {"message": "Hello, world!"}
You can also mock responses with custom headers:
from mimicker.mimicker import mimicker, get
mimicker(8080).routes(
get("/hello")
.body("Hello with headers")
.headers([("Content-Type", "text/plain"), ("Custom-Header", "Value")])
.status(200)
)
# The response will include custom headers
Mimicker allows you to define multiple routes for different HTTP methods and paths. Here's an example with GET
and POST
routes:
from mimicker.mimicker import mimicker, get, post
mimicker(8080).routes(
get("/greet")
.body({"message": "Hello, world!"})
.status(200),
post("/submit")
.body({"result": "Submission received"})
.status(201)
)
# Now the server responds to:
# GET /greet -> {"message": "Hello, world!"}
# POST /submit -> {"result": "Submission received"}
You can also mock different HTTP status codes for the same endpoint:
from mimicker.mimicker import mimicker, get
mimicker(8080).routes(
get("/status")
.body({"message": "Success"})
.status(200),
get("/error")
.body({"message": "Not Found"})
.status(404)
)
# GET /status -> {"message": "Success"} with status 200
# GET /error -> {"message": "Not Found"} with status 404
Mimicker supports JSON bodies, making it ideal for API testing:
from mimicker.mimicker import mimicker, get
mimicker(8080).routes(
get("/json")
.body({"message": "Hello, JSON!"})
.status(200)
)
# The response will be: {"message": "Hello, JSON!"}
This is useful when testing how your code handles timeouts when calling a web API.
from mimicker.mimicker import mimicker, get
import requests
mimicker(8080).routes(
get("/wait").
delay(0.5).
body("the client should have timed out")
)
try:
resp = requests.get("http://localhost:8080/wait", timeout=0.2)
except requests.exceptions.ReadTimeout as error:
print(f"the API is unreachable due to request timeout: {error=}")
else:
# do things with the response
...
In addition to JSON bodies, Mimicker supports other types of content for the response body. Here's how you can return text or file content:
from mimicker.mimicker import mimicker, get
mimicker(8080).routes(
get("/text")
.body("This is a plain text response")
.status(200)
)
# The response will be plain text: "This is a plain text response"
You can also return files from a mock endpoint:
from mimicker.mimicker import mimicker, get
mimicker(8080).routes(
get("/file")
.body(open("example.txt", "rb").read()) # Mock a file response
.status(200)
)
# The response will be the content of the "example.txt" file
Mimicker allows dynamic responses based on the request data using response_func
.
This feature enables you to build mock responses that adapt based on request parameters, headers, and body.
from mimicker.mimicker import mimicker, post
# Available for use with response_func:
# kwargs.get("payload")
# kwargs.get("headers")
# kwargs.get("params")
def custom_response(**kwargs):
request_payload = kwargs.get("payload")
return 200, {"message": f"Hello {request_payload.get('name', 'Guest')}"}
mimicker(8080).routes(
post("/greet")
.response_func(custom_response)
)
# POST /greet with body {"name": "World"} -> {"message": "Hello World"}
# POST /greet with empty body -> {"message": "Hello Guest"}
get(path)
: Defines aGET
endpoint.post(path)
: Defines aPOST
endpoint.put(path)
: Defines aPUT
endpoint.delete(path)
: Defines aDELETE
endpoint.patch(path)
: Defines aPATCH
endpoint..delay(duration)
: Defines the delay in seconds waited before returning the response (optional, 0. by default)..body(content)
: Defines the responsebody
..status(code)
: Defines the responsestatus code
..headers(headers)
: Defines responseheaders
..response_func(func)
: Defines a dynamic response function based on the request data.
Mimicker supports Python 3.7 and above.
You are welcome to report π or issues, upvote π feature requests, or π£οΈ discuss features and ideas @ slack community
I'm thankful to all the people who have contributed to this project.
Mimicker is released under the MIT License. see the LICENSE for more information.