Reputation: 193
I have a test helper function createUser
that makes an HTTP request to the backend API to create a user. The backend API calls a method on Auth0 client to create a user. The responses I have are set for Auth0 client URL path /api/v2/users
.
I am testing a service that has two types of users - an owner of the account and the invitee user. I am calling a helper twice before all the tests:
const owner = await createUser('[email protected]');
const invitee = await createUser('[email protected]');
And I expect owner
to have [email protected]
as an email and an [email protected]
email for invitee
.
In order to return two different responses I used Wiremock scenarios. And currently I have the responses like this:
User #1
{
"scenarioName": "user-scenario",
"requiredScenarioState": "Started",
"newScenarioState": "owner-user",
"request": {
"method": "POST",
"urlPattern": "/api/v2/users"
},
"response": {
"status": 201,
"headers": {
"Content-Type": "application/json"
},
"jsonBody": {
"email": "[email protected]"
}
}
}
User #2
{
"scenarioName": "user-scenario",
"requiredScenarioState": "owner-user",
"request": {
"method": "POST",
"urlPattern": "/api/v2/users"
},
"response": {
"status": 201,
"headers": {
"Content-Type": "application/json"
},
"jsonBody": {
"email": "[email protected]"
}
}
}
When I run the tests Wiremock returns the second response for both createUser
calls. The second response was created after the first and Wiremock prioritizes the most recently created response. I decided to set the priority: 1
on the first response to force Wiremock to return it and therefore change the scenario state. That worked only on the first test run but not for the subsequent ones.
Sometimes if I delete the Wiremock Docker image and start the container from scratch it returns the responses as expected but then continues returning the second response for both calls.
What am I doing wrong and if it's not how I set up the scenarios what could be the possible reasons for such inconsistency?
Upvotes: 3
Views: 4032
Reputation: 1512
Multiple ways to skin this cat - third (response templating) is probably best.
The first request moves the scenario into state owner-user
, and after that all requests will return user #2 for the lifetime of the WireMock instance - in your case, the docker container - unless it is reset.
You can reset it as so: PUT /__admin/scenarios/user-scenario/Started
.
The state of a scenario is held in memory, so restarting the container should also reset the state to Started
.
See WireMock | Stateful Behaviour | Resetting a single scenario
You may not need to use scenarios at all. You can use the request body of the POST to decide which stub to call, based on the email address you are sending.
Assuming your request payload looks like this:
{
"email": "[email protected]"
}
You can match on the request body as so:
{
"request": {
"method": "POST",
"urlPattern": "/api/v2/users",
"bodyPatterns": [
{
"matchesJsonPath": {
"expression": "$.email",
"equalTo": "[email protected]",
}
}
]
},
"response": {
"status": 201,
"headers": {
"Content-Type": "application/json"
},
"jsonBody": {
"email": "[email protected]"
}
}
}
{
"request": {
"method": "POST",
"urlPattern": "/api/v2/users",
"bodyPatterns": [
{
"matchesJsonPath": {
"expression": "$.email",
"equalTo": "[email protected]",
}
}
]
},
"response": {
"status": 201,
"headers": {
"Content-Type": "application/json"
},
"jsonBody": {
"email": "[email protected]"
}
}
}
See WireMock | Request Matching | JSON Path for details.
You can use values passed to WireMock in the request in the response using response templating as so:
{
"request": {
"method": "POST",
"urlPattern": "/api/v2/users"
},
"response": {
"status": 201,
"headers": {
"Content-Type": "application/json"
},
"transformers": ["response-template"],
"jsonBody": {
"email": "{{jsonPath request.body '$.email'}}"
}
}
}
See WireMock | Response Templating | JSONPath helper for details.
There are also a variety of helpers for generating random data in various formats should you need each request to return some different value (e.g. a UUID) - see WireMock | Response Templating | Random value helper for details.
Upvotes: 4