REST assured

Overview

A tool for stubbing/mocking external http based services that app under test is talking to. This is useful for blackbox testing or in cases where it is not possible to access application objects directly from test code. There are three main use cases:

  • stubbing out external data sources with predefined data, so that test code has known data to assert against
  • setting expectations on messages to external services (currently not yet implemented)
  • mimic different responses from external services during development. For that purpose there is web UI

Usage

You are going to need ruby >= 1.8.7. Install gem and run:

bash$ sudo gem install rest-assured # omit sudo if using rvm
bash$ rest-assured &

Or clone from github and run:

bash$ git clone [email protected]:BBC/rest-assured.git
bash$ cd rest-assured && bundle install # `gem install bundler` if command not found
bash$ ./bin/rest-assured &

This starts an instance of rest-assured on port 4578 (changable with --port option) and creates rest-assured.db (changable with --database option) in the current directory. You can now access it via REST or web interfaces on http://localhost:4578

Doubles

Double is a stub/mock of a particular external call. There is the following rest API for setting up doubles:

  • POST '/doubles', { fullpath: path, content: content, method: method } Creates double with the following parameters:

    • fullpath - e.g., /some/api/object, or with parameters in query string (useful for doubling GETs) - /some/other/api/object?a=2&b=c. Mandatory.
    • content - whatever you want this double to respond with. Mandatory.
    • method - one of http the following http verbs: GET, POST, PUT, DELETE. Optional. GET is default.

Example (using ruby RestClient):

RestClient.post 'http://localhost:4578:/doubles', { request_fullpath: '/api/v2/products?type=fresh', method: 'GET', content: 'this is list of products' }

Now GETting http://localhost:4578/api/v2/products?type=fresh (in browser for instance) should return "this is list of products".

If there is more than one double for the same request_fullpath and method, the last created one gets served. In UI you can manually control which double is 'active' (gets served).

  • DELETE '/doubles/all' Deletes all doubles.

Redirects

It is sometimes desirable to only double certain calls while letting others through to the 'real' services. Meet Redirects. Kind of "rewrite rules" for requests that didn't match any double. Here is the rest API for managing redirects:

  • POST '/redirects', { pattern: pattern, to: uri } Creates redirect with the following parameters:

    • pattern - regex (perl5 style) tested against request fullpath. Mandatory
    • to - url base e.g., https://myserver:8787/api. Mandatory

Example (using ruby RestClient):

RestClient.post 'http://localhost:4578/redirects', { pattern: '^/auth', to: 'https://myserver.com/api' }

Now request (any method) to http://localhost:4578/auth/services/1 will get redirected to https://myserver.com/api/auth/services/1. Provided of course there is no double matched for that fullpath and method. Much like rewrite rules, redirects are evaluated in order (of creation). In UI you can manually rearrange the order.

Storage

By default when you start rest-assured it creates (unless already exists) sqlite database and stores it into file in the current directory. This is good for using it for development - when you want doubles/redirects to persist across restarts - but may not be so desirable for using with tests, where you want each test run to start from blank slate. For that reason, you can specify --database :memory: so that database is kept in memory.

Logging

It is sometimes useful to see what requests rest-assured is being hit. Either to explore what requests your app is making or to check that test setup is right and doubles indeed get returned. By default, when started, rest-assured creates log file in the current directory. This is configurable with --logfile option.

TODO

  • Implement expectations
  • Support headers (extends previous point)
  • Ruby client library
  • Support methods in UI (at the moment it is always GET)
  • Don't allow to double internal routes. Just in case

Author

Artem Avetisyan