This gem allows you to double external HTTP services using Sinatra. Your server(s) will be run in the background using Thin each time you run your tests/specs.
Installation
$ gem install http-double
Usage
First, define a server double:
require 'http-double'
class HelloDouble < HttpDouble::Base
get '/hello' do
[
200,
{'Content-Type' => 'application/json'},
['{"greeting":"Hello!"}']
]
end
end
Then background it in your spec helper or test setup routine, specifying a local address and port:
HelloDouble.background '127.0.0.1', 1357
You can now write functional tests against your double, using no-nonsense HTTP over honest-to-goodness TCP.
describe 'The "Hello" server' do
it 'should greet me politely' do
response = Net::HTTP.get_response(URI 'http://127.0.0.1:1357/hello').body
expect(response).to include 'Hello!'
end
end
Expectations on Traffic
Every request/response to/from an HTTP double is recorded in its log
. To use the log effectively, clear it before each test.
before :each do
HelloDouble.log.clear
end
Each member of the log
array contains a request
and a response
. Here's a contrived example:
describe 'The "Hello" server' do
it 'should record traffic' do
log = HelloDouble.log
Net::HTTP.get_response URI 'http://127.0.0.1:1357/hello'
expect(log.count).to be 1
expect(log.last.request.verb).to be :get
expect(log.last.request.path).to eq '/hello'
expect(log.last.request.body).to be_nil
expect(log.last.response.code).to be 200
expect(log.last.response.headers['Content-Type']).to eq 'application/json'
expect(JSON.parse(log.last.response.body)['greeting']).to eq 'Hello!'
end
end
In functional tests, you will tend to mostly want to test what your application sends. The log's request object lets you set expectations using indexed access:
def be_a_cowboy!
uri = URI 'http://127.0.0.1:1357/hello'
Net::HTTP.post_form uri, 'new_greeting' => 'Howdy!'
end
describe 'Something that changes my greeting' do
it 'should act like a cowboy' do
be_a_cowboy!
request = HelloDouble.log.last.request
expect(request.verb).to be :post
expect(request.path).to eq '/hello'
expect(request['new_greeting']).to eq 'Howdy!'
end
end
You can use indexed access on any request sent as valid application/x-www-form-urlencoded
or application/json
.