Package Exports
- dynamock
- dynamock/src/createServer.js
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (dynamock) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
dynamock
dynamock is a dynamic mock/fixture HTTP server designed for functional testing.
Installation
yarn add dynamock -D
# or NPM
npm install dynamock --save-devUsage
⚠️ Security
Be aware of running your dynamock server in a CLOSED network, there is no authentication required to configure it.
It is highly recommended using dynamock for dev/testing purpose ONLY.
Run the server (NodeJS required)
# dynamock PORT [HOST]
dynamock 3001Inject fixtures
fetch('http://localhost:3001/___fixtures', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
request: {
method: 'GET',
path: '/products/1'
},
response: {
body: {
id: 1
}
}
})
})Consume fixtures
fetch('http://localhost:3001/products/1', { method: 'GET' })
.then(response => response.json())
.then(response => assert.equal(response, { id: 1 }))Dynamock is designed to remove the fixture once consumed, see options.lifetime to adapt this behavior.
fetch('http://localhost:3001/products/1', { method: 'GET' }).then(response => assert.equal(response.status, 404))Property response matching
By default, dynamock uses partial matching for headers, query and cookies.
Configuration api
Using the configuration is optional. However, it gives the ability of reusing redundant data across requests and simplifying fixtures setup.
/___config - Retrieve configuration
Responses
- Status 200 - OK
{
"cors": "{null|'*'} - '*' allows all requests via cors headers, this creates a global route OPTIONS",
"headers": "{object} - Dictionary of headers (object) by name (string)",
"query": "{object} - Dictionary of query (object) by name (string)",
"cookies": "{object} - Dictionary of cookies (object) by name (string)"
}Example:
{
"cors": null,
"headers": {},
"query": {},
"cookies": {}
}
/___config - Update configuration
Request
- Body
{
"cors": "{null|'*'} [default=null] - '*' allows all requests via cors headers, this creates a global route OPTIONS",
"headers": "{object} [default={}] - Dictionary of headers (object) by name (string)",
"query": "{object} [default={}] - Dictionary of query (object) by name (string)",
"cookies": "{object} [default={}] - Dictionary of cookies (object) by name (string)"
}Example:
{
"cors": "*",
"headers": {
"apiBearer": {
"Authorization": "Bearer xyz"
}
}
}Responses
- Status 200 - OK
{
"cors": "{null|'*'}",
"headers": "{object}",
"query": "{object}",
"cookies": "{object}"
}Example:
{
"cors": null,
"headers": {
"captcha": {
"X-CAPTCHA-TOKEN": "fake"
},
"cors": {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "*",
"Access-Control-Allow-Headers": "*"
}
},
"query": {
"campaign": {
"utm_source": "x",
"utm_campaign": "y"
}
},
"cookies": {
"anonymousUser": {
"PHPSESSID": "x"
},
"loggedInUser": {
"PHPSESSID": "y"
}
}
}- Status 400 - BAD REQUEST
Wrong configuration format
/___config - Reset configuration
Responses
- Status 204 - NO CONTENT
Fixtures api
A fixture is composed of:
- request data to match the incoming requests
- response data to define the result(s) of the requests
/___fixtures - Add fixture
Request
- Body
{
"request": {
"method": "{string} - Http method to match requests, case insensitive, use wildcard '*' to match all",
"path": "{string} - Http path to match requests, use wildcard '*' to match all",
"headers": "{object|array} [default={}] - Headers to match requests",
"query": "{object|array} [default={}] - Query to match requests",
"cookies": "{object|array} [default={}] - Cookies to match requests",
"body": "{object} [default=``] - Body to match requests",
"options": {
"path": {
"allowRegex": "{boolean} [default=false] - Allow matching RegExp",
"disableEncodeURI": "{boolean} [default=false] - Disable encode URI, always on when allowRegex is true"
},
"method": {
"allowRegex": "{boolean} [default=false] - Allow matching RegExp"
},
"headers": {
"strict": "{boolean} [default=false] - Strictly match headers",
"allowRegex": "{boolean} [default=false] - Allow matching RegExp"
},
"cookies": {
"strict": "{boolean} [default=false] - Strictly match cookies",
"allowRegex": "{boolean} [default=false] - Allow matching RegExp"
},
"query": {
"strict": "{boolean} [default=false] - Strictly match query",
"allowRegex": "{boolean} [default=false] - Allow matching RegExp"
},
"body": {
"strict": "{boolean} [default=false] - Strictly match body",
"allowRegex": "{boolean} [default=false] - Allow matching RegExp"
}
}
},
"response": {
"status": "{number} [default=200] - Response status code",
"headers": "{object|array} [default={}] - Response headers",
"cookies": "{object|array} [default={}] - Response cookies",
"body": "{string|object|array} [default=``] - Body to response",
"filepath": "{string} [default=``] - Absolute filepath to serve with auto mime-types",
"options": {
"delay": "{number} [default=0] - Delay the response with a number of milliseconds",
"lifetime": "{number} [default=1] - Number of times the fixture can be consumed before getting removed, use 0 for unlimited consumption"
}
},
"responses": "{array} [default=[]] - Array of responses"
}Examples:
{
"request": {
"method": "GET",
"path": "/pandas"
},
"response": {
"body": [{ "id": "1" }, { "id": "2" }]
}
}{
"request": {
"method": "GET",
"path": "/cdn/images/fennec.jpg"
},
"response": {
"filepath": "/absolute/path/tofennec.jpg",
"options": {
"delay": 1000
}
}
}{
"request": {
"method": "POST",
"path": "/heros",
"body": {
"name": "po",
"type": "panda"
},
"options": {
"body": {
"strict": true
}
}
},
"response": {
"body": {
"id": "1",
"name": "po",
"type": "panda"
}
}
}{
"request": {
"method": "OPTIONS",
"path": "*"
},
"response": {
"headers": {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "*",
"Access-Control-Allow-Headers": "*"
},
"body": ""
}
}{
"request": {
"method": "get",
"path": "/"
},
"responses": [
{
"body": "first return"
},
{
"body": "second return"
}
]
}{
"request": {
"method": "GET",
"path": "/",
"headers": {
"user-agent": "/firefox/70$/i"
},
"options": {
"headers": {
"allowRegex": true
}
}
},
"response": {
"body": "Only for Firefox 70 users !"
}
}{
"request": {
"method": "GET",
"path": "/%20a",
"options": {
"path": {
"disableEncodeURI": true
}
}
},
"response": {
"body": "This will match '/ a' or '/%20a' calls"
}
}Responses
- Status 200 - OK
{
"id": "{string}"
}Example:
{
"id": "38ed32e9fb0a1e5c7cb1b6f0ff43f6060d8b4508"
}- Status 400 - BAD REQUEST
The configuration is not valid
- Status 409 - CONFLICT
Route {METHOD} ${PATH} is already registered.
/___fixtures/bulk - Bulk add fixtures
It is meant to setup multiple fixtures at once.
Request
- Body
[
{
"request": {
"method": "{string} - Http method to match requests, case insensitive, use wildcard '*' to match all",
"path": "{string} - Http path to match requests, use wildcard '*' to match all",
"headers": "{object|array} [default={}] - Headers to match requests",
"query": "{object|array} [default={}] - Query to match requests",
"cookies": "{object|array} [default={}] - Cookies to match requests",
"body": "{object} [default=``] - Body to match requests",
"options": {
"path": {
"allowRegex": "{boolean} [default=false] - Allow matching RegExp"
},
"method": {
"allowRegex": "{boolean} [default=false] - Allow matching RegExp"
},
"headers": {
"strict": "{boolean} [default=false] - Strictly match headers",
"allowRegex": "{boolean} [default=false] - Allow matching RegExp"
},
"cookies": {
"strict": "{boolean} [default=false] - Strictly match cookies",
"allowRegex": "{boolean} [default=false] - Allow matching RegExp"
},
"query": {
"strict": "{boolean} [default=false] - Strictly match query",
"allowRegex": "{boolean} [default=false] - Allow matching RegExp"
},
"body": {
"strict": "{boolean} [default=false] - Strictly match body",
"allowRegex": "{boolean} [default=false] - Allow matching RegExp"
}
}
},
"response": {
"status": "{number} [default=200] - Response status code",
"headers": "{object|array} [default={}] - Response headers",
"cookies": "{object|array} [default={}] - Response cookies",
"body": "{string|object|array} [default=``] - Body response",
"filepath": "{string} [default=``] - Absolute filepath to serve with auto mime-types",
"options": {
"delay": "{number} [default=0] - Delay the response with a number of milliseconds",
"lifetime": "{number} [default=1] - Number of times the fixture can be consumed before getting removed, use 0 for unlimited consumption"
}
},
"responses": "{array} [default=[]] - Array of responses"
}
]Examples:
[
{
"request": {
"method": "GET",
"path": "/pandas"
},
"response": {
"body": [{ "id": "1" }, { "id": "2" }]
}
},
{
"request": {
"method": "GET",
"path": "/cdn/images/fennec.jpg"
},
"response": {
"filepath": "/absolute/path/tofennec.jpg"
}
}
]Responses
- Status 200 - OK
[
{
"id": "{string}"
}
]Example:
[
{
"id": "38ed32e9fb0a1e5c7cb1b6f0ff43f6060d8b4508"
},
{
"id": "086c67ef89fd832deeae33b209e6e8ecc6b32003"
}
]- Status 400 - BAD REQUEST
The fixture is not valid
- Status 409 - CONFLICT
Another fixture with the same request is already registered
/___fixtures/:id - Delete a fixture
Request
- Params
{
"id": "{string}"
}Example:
DELETE /___fixtures/38ed32e9fb0a1e5c7cb1b6f0ff43f6060d8b4508Responses
- Status 204 - NO CONTENT
/___fixtures - Delete all fixtures
Responses
- Status 204 - NO CONTENT
Next features
- Handle other web protocols like https or websocket
- Security tokens for public environments