MOUNTEBANK AND
YOU
Nagesh Kumar
nkumar@thoughtworks.com
1
AGENDA
Integration Testing
Isolation Testing
Real Problem
Mountebank
Quick Watch
Whom to Catch
2
Test multiple components at the same time
No GUI
No faking/mocking/stubbing/etc
Need Real things to Integrate With
Real Services must be reliable and need to be fast
THE CLASSICAL VIEW OF INTEGRATION TESTING
3
THE CLASSICAL VIEW OF ISOLATION TESTING
4
Test as many real components at the same time
Stub out the unreliable Real Dependency
Stub out the non-existing Real Dependency
Testing our code while isolating it from the naughty Real
Dependency
YOU CAN’T ALWAYS FIX THE REAL PROBLEM (SAD, BUT TRUE)
5
Real Things being maintained/developed by other teams
Poor testing environment (Hardware, Data, Other)
Fixing the Real Thing is more costly than enduring it
Client won’t pay us to fix the Real Things
WHAT IS MOUNTEBANK?
“mountebank is the
first tool to provide
cross-platform, multi-
protocol test doubles
over the wire.”
- mountebank
6
http://www.mbtest.org/
WHY MOUNTEBANK?
Proprietary
Lacked platform support
Lacked protocol support
Not extensible
Slow
Hard to run during unit test cycle
Managed through a special IDE
7
Existing tools were:
WHAT CAN IT DO FOR ME?
Record live requests and responses to replay later
Imitate a response from scratch
Respond to specific requests via predicates
Track any requests that come its way
8
AN OVERVIEW OF MOUNTEBANK IN ACTION
System
Under Test
Tests
Mountebank
Stub
WHAT DO I NEED TO KNOW IN MB?
Imposters
Predicates
Proxies
Injection
Behaviors
10
WHAT ARE IMPOSTERS?
The imposter is the
most integral part of
mountebank. An
imposter is associated
with a port number
and a protocol. It
contains within itself
the response we want
to return, and other
related information.
11
http://www.mbtest.org/docs/api/stubs
ANATOMY OF AN IMPOSTER
POST /imposters HTTP/1.1
Host: localhost:2525
Accept: application/json
Content-Type: application/json
{
"port": 4545,
"protocol": “http",
"stubs": [
{
"responses": [
{
"is": {
"statusCode": 200, (Will default to 200 if not provided)
“headers": {
“Content-Type": “text/plain“
},
"body": “Hello world!”
}
}
]
}
]
}
12
ANOTHER IMPOSTER EXAMPLE
POST /imposters HTTP/1.1
Host: localhost:2525
Accept: application/json
Content-Type: application/json
{
"port": 4546,
"protocol": "http",
"stubs": [
{
"responses": [
{
"is": {
"statusCode": 201,
“headers": {
“Content-Type": “text/plain“
},
"body": “Created!”
}
},
{
"is": {
"statusCode": 400,
“headers": {
“Content-Type": “text/plain“
},
"body": “ERROR: Already Exists!”
}
}
]
}
]
}
13
WHAT IS A PREDICATE?
The predicate is the
part of an imposter
which determines if a
request should be
responded to by said
imposter.
14
http://www.mbtest.org/docs/api/predicates
TYPES OF PREDICATES
Equals
Deep Equals
Contains
Starts/EndsWith
Matches
Exists
Not/And/Or
Inject
http://www.mbtest.org/docs/api/predicates
15
WHAT CAN A PREDICATE OPERATE ON?
That depends on the
protocol you’re using!
For example, Http
allows you to use
predicates on:
- Method Type
- Query Path
- Request Body
- And More!
16
http://www.mbtest.org/docs/protocols/http
PREDICATE EXAMPLE
{
"port": 4551,
"protocol": "http",
"stubs": [
{
"responses": [
{
"is": {
"statusCode": 201,
"headers": {
"Content-Type": "text/plain"
},
"body": "You posted to me!"
}
}
],
"predicates": [
{
"equals": {
"method": "POST"
}
}
]
}
]
}
17
OR EXAMPLE
{
"port": 4552,
"protocol": "http",
"stubs": [
{
"responses": [
{
"is": {
"statusCode": 201,
"headers": {
"Content-Type": "text/plain"
},
"body": "You posted to me!"
}
}
],
"predicates": [
{
"or": [
{
"equals": {
"method": "POST"
}
},
{
"equals": {
"method": "PUT"
}
}
]
}
]
}
]
}
18
WHAT IS A PROXY?
The proxy is a special
imposter which allows
us to get between our
application and a
service it
communicates with. It
records each request,
forwards it to the
service, and records
the response from that
service.
19
http://www.mbtest.org/docs/api/proxies
BUT WHAT DO I DO WITH IT?
Record responses that would be difficult (if not impossible)
to write by hand
Look at requests to see what distinguishes them from each
other
20
PROXY EXAMPLE
{
"port": 4560,
"protocol": "http",
"name": "duckduckgo",
"stubs": [
{
"responses": [
{
"proxy": {
"to": "http://api.duckduckgo.com/",
"mode": "proxyOnce",
"predicateGenerators": [
{
"matches": {
"method": true,
"path": true,
"query": true
}
}
]
}
}
]
}
]
}
21
Direct all Suggestions to Brandon
(bbyars@thoughtworks.com)
THANK YOU

Mountebank and you

  • 1.
  • 2.
    AGENDA Integration Testing Isolation Testing RealProblem Mountebank Quick Watch Whom to Catch 2
  • 3.
    Test multiple componentsat the same time No GUI No faking/mocking/stubbing/etc Need Real things to Integrate With Real Services must be reliable and need to be fast THE CLASSICAL VIEW OF INTEGRATION TESTING 3
  • 4.
    THE CLASSICAL VIEWOF ISOLATION TESTING 4 Test as many real components at the same time Stub out the unreliable Real Dependency Stub out the non-existing Real Dependency Testing our code while isolating it from the naughty Real Dependency
  • 5.
    YOU CAN’T ALWAYSFIX THE REAL PROBLEM (SAD, BUT TRUE) 5 Real Things being maintained/developed by other teams Poor testing environment (Hardware, Data, Other) Fixing the Real Thing is more costly than enduring it Client won’t pay us to fix the Real Things
  • 6.
    WHAT IS MOUNTEBANK? “mountebankis the first tool to provide cross-platform, multi- protocol test doubles over the wire.” - mountebank 6 http://www.mbtest.org/
  • 7.
    WHY MOUNTEBANK? Proprietary Lacked platformsupport Lacked protocol support Not extensible Slow Hard to run during unit test cycle Managed through a special IDE 7 Existing tools were:
  • 8.
    WHAT CAN ITDO FOR ME? Record live requests and responses to replay later Imitate a response from scratch Respond to specific requests via predicates Track any requests that come its way 8
  • 9.
    AN OVERVIEW OFMOUNTEBANK IN ACTION System Under Test Tests Mountebank Stub
  • 10.
    WHAT DO INEED TO KNOW IN MB? Imposters Predicates Proxies Injection Behaviors 10
  • 11.
    WHAT ARE IMPOSTERS? Theimposter is the most integral part of mountebank. An imposter is associated with a port number and a protocol. It contains within itself the response we want to return, and other related information. 11 http://www.mbtest.org/docs/api/stubs
  • 12.
    ANATOMY OF ANIMPOSTER POST /imposters HTTP/1.1 Host: localhost:2525 Accept: application/json Content-Type: application/json { "port": 4545, "protocol": “http", "stubs": [ { "responses": [ { "is": { "statusCode": 200, (Will default to 200 if not provided) “headers": { “Content-Type": “text/plain“ }, "body": “Hello world!” } } ] } ] } 12
  • 13.
    ANOTHER IMPOSTER EXAMPLE POST/imposters HTTP/1.1 Host: localhost:2525 Accept: application/json Content-Type: application/json { "port": 4546, "protocol": "http", "stubs": [ { "responses": [ { "is": { "statusCode": 201, “headers": { “Content-Type": “text/plain“ }, "body": “Created!” } }, { "is": { "statusCode": 400, “headers": { “Content-Type": “text/plain“ }, "body": “ERROR: Already Exists!” } } ] } ] } 13
  • 14.
    WHAT IS APREDICATE? The predicate is the part of an imposter which determines if a request should be responded to by said imposter. 14 http://www.mbtest.org/docs/api/predicates
  • 15.
    TYPES OF PREDICATES Equals DeepEquals Contains Starts/EndsWith Matches Exists Not/And/Or Inject http://www.mbtest.org/docs/api/predicates 15
  • 16.
    WHAT CAN APREDICATE OPERATE ON? That depends on the protocol you’re using! For example, Http allows you to use predicates on: - Method Type - Query Path - Request Body - And More! 16 http://www.mbtest.org/docs/protocols/http
  • 17.
    PREDICATE EXAMPLE { "port": 4551, "protocol":"http", "stubs": [ { "responses": [ { "is": { "statusCode": 201, "headers": { "Content-Type": "text/plain" }, "body": "You posted to me!" } } ], "predicates": [ { "equals": { "method": "POST" } } ] } ] } 17
  • 18.
    OR EXAMPLE { "port": 4552, "protocol":"http", "stubs": [ { "responses": [ { "is": { "statusCode": 201, "headers": { "Content-Type": "text/plain" }, "body": "You posted to me!" } } ], "predicates": [ { "or": [ { "equals": { "method": "POST" } }, { "equals": { "method": "PUT" } } ] } ] } ] } 18
  • 19.
    WHAT IS APROXY? The proxy is a special imposter which allows us to get between our application and a service it communicates with. It records each request, forwards it to the service, and records the response from that service. 19 http://www.mbtest.org/docs/api/proxies
  • 20.
    BUT WHAT DOI DO WITH IT? Record responses that would be difficult (if not impossible) to write by hand Look at requests to see what distinguishes them from each other 20
  • 21.
    PROXY EXAMPLE { "port": 4560, "protocol":"http", "name": "duckduckgo", "stubs": [ { "responses": [ { "proxy": { "to": "http://api.duckduckgo.com/", "mode": "proxyOnce", "predicateGenerators": [ { "matches": { "method": true, "path": true, "query": true } } ] } } ] } ] } 21
  • 22.
    Direct all Suggestionsto Brandon (bbyars@thoughtworks.com) THANK YOU

Editor's Notes

  • #5 Replace Real Things with Dependency