Getting Started
The typical sequence for using MockServer is as follows:
- Start MockServer
- Setup Expectations
- Run Test Scenario
- Verify Requests
0. Start MockServer
MockServer is flexible and support numerous usage patterns.
The MockServer and MockServer Proxy can be run:
- via a Maven Plugin as part of a Maven build cycle
- programmatically via a Java API in an @Before or @After method
- using a JUnit @Rule via a @Rule annotated field in a JUnit test
- from the command line as a stand-alone process in a test environment
- as a deployable WAR to an existing application server
- as a Node.js (npm) module from any Node.js code
- as a Grunt plugin as part of a Grunt build cycle
- as a Docker container in any Docker enabled environment
MockServer and MockServer Proxy is available as:
- a stand alone Netty web server that is fully self contained
- a deployable WAR that runs on any JEE web server
- a maven plugin
- an npm plugin
- a Grunt plugin
- a fully encapsulated Docker container
- a Homebrew package
It is also possible to build and run MockServer directly from source code
To simplify configuration all MockServer versions (except the deployable WAR) only use a single port to support HTTP, HTTPS and SOCKS. This is achieved by dynamically detecting if the client is using HTTP, HTTPS or SOCKS.
1. Setup Expectations
To mock an HTTP / HTTPS interaction an expectation is setup specifying how a request should be matched and what action MockServer should take when the request has been matched.
When a request is matched there are three actions that can be defined as follows:
- respond - return a "mock" response
- forward - forward the request
- callback - execute a callback
Java Examples
The following Java example shows the creation of an simple expectation with a respond action:
new MockServerClient("localhost", 1080)
.when(
request()
.withMethod("POST")
.withPath("/login")
.withBody("{username: 'foo', password: 'bar'}")
)
.respond(
response()
.withStatusCode(302)
.withCookie(
"sessionId", "2By8LOhBmaW5nZXJwcmludCIlMDAzMW"
)
.withHeader(
"Location", "https://www.mock-server.com"
)
);
The following Java example shows the creation of a more complex expectation with a respond action:
new MockServerClient("localhost", 1080)
.when(
request()
.withMethod("POST")
.withPath("/login")
.withQueryStringParameters(
new Parameter("returnUrl", "/account"),
new Parameter("_timestamp", "1430199066291")
)
.withCookie("sessionId", "2By8LOhBmaW5nZXJwcmludCIlMDAzMW")
.withBody(json("{username: 'foo', password: 'bar'}", MatchType.STRICT)),
Times.exactly(1),
TimeToLive.exactly(TimeUnit.MINUTES, 5l)
)
.respond(
response()
.withStatusCode(401)
.withHeaders(
new Header("Content-Type", "application/json; charset=utf-8"),
new Header("Cache-Control", "public, max-age=86400")
)
.withBody("{ message: 'incorrect username and password combination' }")
.withDelay(new Delay(TimeUnit.SECONDS, 1))
);
JavaScript Examples
The following JavaScript example shows the creation of an simple expectation with a respond action:
mockServerClient("localhost", 1080).mockAnyResponse({
"httpRequest": {
"method": "POST",
"path": "/login",
"body": "{username: 'foo', password: 'bar'}"
},
"httpResponse": {
"statusCode": 302,
"headers": [
{
"name": "Location",
"values": "https://www.mock-server.com"
}
],
"cookies": [
{
"name": "sessionId",
"value": "2By8LOhBmaW5nZXJwcmludCIlMDAzMW"
}
]
}
});
The following JavaScript example shows the creation of a more complex expectation with a respond action:
mockServerClient("localhost", 1080).mockAnyResponse({
"httpRequest": {
"method": "POST",
"path": "/login",
"queryStringParameters": [
{
"name": "returnUrl",
"values": ["/account"]
},
{
"name": "_timestamp",
"values": ["1430199066291"]
}
],
"cookies": [
{
"name": "sessionId",
"values": ["2By8LOhBmaW5nZXJwcmludCIlMDAzMW"]
}
],
"body": {
"type": "JSON",
"value": JSON.stringify({ username: "foo", password: "bar" }),
"matchType": "STRICT"
}
},
"httpResponse": {
"statusCode": 401,
"headers": [
{
"name": "Content-Type",
"values": ["application/json; charset=utf-8"]
},
{
"name": "Cache-Control",
"values": ["public, max-age=86400"]
}
],
"body": JSON.stringify({ message: "incorrect username and password combination" }),
"delay": {
"timeUnit": "SECONDS",
"value": 1
}
},
"times": {
"remainingTimes": 1,
"unlimited": false
},
"timeToLive": {
"timeUnit": "MINUTES,
"timeToLive": 5,
"unlimited": false
}
});
Ruby Examples
The following Ruby example shows the creation of an simple expectation with a respond action:
client = MockServerClient.new('localhost', 1080)
expectation = expectation do |expectation|
expectation.request do |request|
request.method = 'POST'
request.path = '/login'
request.body = exact({ username: 'foo', password: 'bar' }.to_json)
end
expectation.response do |response|
response.status_code = 302
response.headers << header('Location', 'https://www.mock-server.com')
end
end
client.register(expectation)
The following Ruby example shows the creation of a more complex expectation with a respond action:
client = MockServerClient.new('localhost', 1080)
expectation = expectation do |expectation|
expectation.request do |request|
request.method = 'POST'
request.path = '/login'
request.query_string_parameters << parameter('returnUrl', '/account')
request.query_string_parameters << parameter('_timestamp', '1430199066291')
request.cookies = [cookie('sessionId', '2By8LOhBmaW5nZXJwcmludCIlMDAzMW')]
request.body = exact({ username: 'foo', password: 'bar' }.to_json)
end
expectation.response do |response|
response.status_code = 401
response.headers << header('Content-Type', 'application/json; charset=utf-8')
response.headers << header('Cache-Control', 'public, max-age=86400')
response.body = body({ message: 'incorrect username and password combination' }.to_json)
response.delay = delay_by(:SECONDS, 1)
end
expectation.times = exactly(1)
end
client.register(expectation)
Requests can be matched on:
- path - plain text or regular expression
- query string - plain text or regular expression
- headers - plain text or regular expression
- cookies - plain text or regular expression
- body - XPath, JSON, JSON Schema, regular expression, plain text (exact match), or body parameters
The body can be matched using plain text, a JSON object, a JSON schema, an XPath expression or a regular expression
JSON expressions
A JSON expression is a valid JSON object. When a JSON expression is matched against a request body the order of the fields will be ignored, if the exact order is important use a plain text or regular expression matcher.
The JSON expression supports two match types STRICT and ONLY_MATCHING_FIELDS. STRICT match type matches all fields and the order of arrays. In STRICT match type extra fields will cause the matcher to fail. ONLY_MATCHING_FIELDS match type only matches fields provided in the body for the request matcher. ONLY_MATCHING_FIELDS match type will match correctly against a request that contains additional fields or a request that contains any array fields those elements are in a different order.
JSON Schema
For detail of the support JSON Schema syntax see json-schema.org.
XPath
For detail of the support XPath syntax see XPath Expression Syntax.
Regular Expressions
All other matching can be done using plain text or a regular expression, see Pattern (Java Platform SE 6) for supported regular expression syntax.
For more details see the section below on creating expectations.
Actions
When a request is matched there are three actions that can occur as follows:
- respond - return a "mock" response
- forward - forward the request
- callback - execute a callback
Respond Actions
A response action defines a mock response containing:
- status code
- body
- headers
- cookies
Responses can be further controlled using:
- a delay before the response is sent
- the number of times the response is sent (including unlimited)
For more details see the section below on creating expectations.
Forward Actions
A forward action defines how a request should be forwarded and contains:
- host
- port
- scheme
Only the host is mandatory as the port is defaulted to 80 and the scheme is defaulted to HTTP.
For more details see the section below on creating expectations.
Callback Actions
A callback action defines a class that will be used to dynamically generate the response and contains:
- callbackClass
The class must define a default constructor and implement org.mockserver.mock.action.ExpectationCallback.
For more details see the section below on creating expectations.
3. Verify Requests
The MockServer allows the verification of requests by specifying:
- an amount of a single type of request
- a sequence of requests that is verified in order
Verifying Repeating Requests
To verify that the system under test has sent an individual request to MockServer use the verify method of the MockServerClient as follows:
new MockServerClient("localhost", 1090).verify(
request()
.withMethod("POST")
.withPath("/login")
.withBody(exact("{username: 'foo', password: 'bar'}"))
.withCookies(
new Cookie("sessionId", ".*")
),
VerificationTimes.exactly(1)
);
The org.mockserver.verify.VerificationTimes class is used to specify how many times you want MockServer to match a request:
To create an instance of VerificationTimes use one of the static factory methods:
VerificationTimes.once();
VerificationTimes.exactly(int count);
VerificationTimes.atLeast(int count);
Verifying Request Sequences
To verify that the system under test has sent a sequence of requests to MockServer use the verify method of the MockServerClient as follows:
new MockServerClient("localhost", 1090).verify(
request()
.withMethod("POST")
.withPath("/login")
.withBody(exact("{username: 'foo', password: 'bar'}"))
.withCookies(
new Cookie("sessionId", ".*")
),
request()
.withMethod("POST")
.withPath("/deposit")
.withBody(exact("{acccount: '123456789', card: '1234 5678 9012 3456', amount: '10.00'}"))
.withCookies(
new Cookie("sessionId", ".*")
),
request()
.withMethod("POST")
.withPath("/logout")
.withCookies(
new Cookie("sessionId", ".*")
)
);
The each request in the sequence will be verified to have been received at least once, in the exact order specified.