http_stub 0.0.4 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/lib/http_stub.rb CHANGED
@@ -7,7 +7,7 @@ require 'immutable_struct'
7
7
  require 'net/http'
8
8
  require 'json'
9
9
 
10
- require File.expand_path('../http/stub/stub', __FILE__)
11
- require File.expand_path('../http/stub/registry', __FILE__)
12
- require File.expand_path('../http/stub/server', __FILE__)
13
- require File.expand_path('../http/stub/client', __FILE__)
10
+ require File.expand_path('../http_stub/stub', __FILE__)
11
+ require File.expand_path('../http_stub/registry', __FILE__)
12
+ require File.expand_path('../http_stub/server', __FILE__)
13
+ require File.expand_path('../http_stub/client', __FILE__)
@@ -0,0 +1,60 @@
1
+ module HttpStub
2
+
3
+ module Client
4
+
5
+ def self.included(mod)
6
+ mod.extend(HttpStub::Client::ClassMethods)
7
+ mod.send(:include, HttpStub::Client::InstanceMethods)
8
+ end
9
+
10
+ module ClassMethods
11
+
12
+ attr_reader :host_value, :port_value
13
+
14
+ def host(host)
15
+ @host_value = host
16
+ end
17
+
18
+ def port(port)
19
+ @port_value = port
20
+ end
21
+
22
+ end
23
+
24
+ module InstanceMethods
25
+
26
+ def stub!(uri, options)
27
+ response_options = options[:response]
28
+ request = Net::HTTP::Post.new("/stub")
29
+ request.content_type = "application/json"
30
+ request.body = {
31
+ "uri" => uri,
32
+ "method" => options[:method],
33
+ "response" => {
34
+ "status" => response_options[:status] || "200",
35
+ "body" => response_options[:body]
36
+ }
37
+ }.to_json
38
+ response = submit(request)
39
+ raise "Unable to stub request: #{response.message}" unless response.code == "200"
40
+ end
41
+
42
+ alias_method :stub_response!, :stub!
43
+
44
+ def clear!
45
+ request = Net::HTTP::Delete.new("/stubs")
46
+ response = submit(request)
47
+ raise "Unable to clear stubs: #{response.message}" unless response.code == "200"
48
+ end
49
+
50
+ private
51
+
52
+ def submit(request)
53
+ Net::HTTP.new(self.class.host_value, self.class.port_value).start { |http| http.request(request) }
54
+ end
55
+
56
+ end
57
+
58
+ end
59
+
60
+ end
@@ -0,0 +1,26 @@
1
+ module HttpStub
2
+
3
+ class Registry
4
+
5
+ def initialize
6
+ @stubs = []
7
+ end
8
+
9
+ def add(stub, request)
10
+ @stubs.unshift(stub)
11
+ request.logger.info "Stub registered: #{stub}"
12
+ end
13
+
14
+ def find_for(request)
15
+ request.logger.info "Finding stub fulfilling: #{request.inspect}"
16
+ @stubs.find { |stub| stub.stubs?(request) }
17
+ end
18
+
19
+ def clear(request)
20
+ request.logger.info "Clearing stubs"
21
+ @stubs.clear
22
+ end
23
+
24
+ end
25
+
26
+ end
@@ -0,0 +1,56 @@
1
+ module HttpStub
2
+
3
+ class Server < ::Sinatra::Base
4
+
5
+ enable :dump_errors, :logging
6
+
7
+ def initialize
8
+ super()
9
+ @registry = HttpStub::Registry.new
10
+ end
11
+
12
+ private
13
+
14
+ SUPPORTED_REQUEST_TYPES = [:get, :post, :put, :delete, :patch, :options].freeze
15
+
16
+ def self.any_request_type(path, opts={}, &block)
17
+ SUPPORTED_REQUEST_TYPES.each { |type| self.send(type, path, opts, &block) }
18
+ end
19
+
20
+ public
21
+
22
+ # Sample request body:
23
+ # {
24
+ # "uri": "/some/path",
25
+ # "method": "get",
26
+ # "parameters": {
27
+ # "key": "value",
28
+ # ...
29
+ # },
30
+ # "response": {
31
+ # "status": "200",
32
+ # "body": "Hello World"
33
+ # }
34
+ # }
35
+ post "/stub" do
36
+ @registry.add(HttpStub::Stub.new(request), request)
37
+ halt 200
38
+ end
39
+
40
+ delete "/stubs" do
41
+ @registry.clear(request)
42
+ halt 200
43
+ end
44
+
45
+ any_request_type(//) { handle_stub_request }
46
+
47
+ private
48
+
49
+ def handle_stub_request
50
+ stub = @registry.find_for(request)
51
+ stub ? halt(stub.response.status, stub.response.body) : halt(404)
52
+ end
53
+
54
+ end
55
+
56
+ end
@@ -0,0 +1,20 @@
1
+ require File.expand_path('../../http_stub', __FILE__)
2
+ require 'rake/tasklib' unless defined?(::Rake::TaskLib)
3
+
4
+ module HttpStub
5
+
6
+ class StartServerRakeTask < ::Rake::TaskLib
7
+
8
+ def initialize(options)
9
+ desc "Starts stub #{options[:name]}"
10
+ task "start_#{options[:name]}" do
11
+ HttpStub::Server.instance_eval do
12
+ set :port, options[:port]
13
+ run!
14
+ end
15
+ end
16
+ end
17
+
18
+ end
19
+
20
+ end
@@ -0,0 +1,32 @@
1
+ module HttpStub
2
+
3
+ class Stub
4
+
5
+ Response = ImmutableStruct.new(:status, :body)
6
+
7
+ attr_reader :response
8
+
9
+ def initialize(request)
10
+ @data = JSON.parse(request.body.read)
11
+ @response = Response.new(status: @data["response"]["status"], body: @data["response"]["body"])
12
+ end
13
+
14
+ def stubs?(request)
15
+ @data["uri"] == request.path_info &&
16
+ @data["method"].downcase == request.request_method.downcase &&
17
+ parameters == request.params
18
+ end
19
+
20
+ def to_s
21
+ @data.to_s
22
+ end
23
+
24
+ private
25
+
26
+ def parameters
27
+ @data["parameters"] || {}
28
+ end
29
+
30
+ end
31
+
32
+ end
@@ -0,0 +1,3 @@
1
+ module HttpStub
2
+ VERSION = "0.1.1"
3
+ end
@@ -0,0 +1,3 @@
1
+ curl -v -H "Accept: application/json" -H "Content-type: application/json" -X POST -d '{"uri": "/test", "method": "post", "response": {"status":"200", "body":"Foo"}}' http://localhost:8001/stub
2
+
3
+ curl -v -H "Accept: application/json" -H "Content-type: application/json" -X POST -d '' http://localhost:8001/test
@@ -1,8 +1,8 @@
1
- describe Http::Stub::Client do
1
+ describe HttpStub::Client do
2
2
  include_context "server integration"
3
3
 
4
4
  class TestClient
5
- include Http::Stub::Client
5
+ include HttpStub::Client
6
6
 
7
7
  host "localhost"
8
8
  port 8001
@@ -1,14 +1,14 @@
1
- describe Http::Stub::Registry do
1
+ describe HttpStub::Registry do
2
2
 
3
- let(:registry) { Http::Stub::Registry.new }
3
+ let(:registry) { HttpStub::Registry.new }
4
4
 
5
5
  let(:logger) { double("Logger").as_null_object }
6
- let(:request) { double("HttpRequest", logger: logger, to_s: "Request as String") }
6
+ let(:request) { double("HttpRequest", logger: logger, inspect: "Request inspect result") }
7
7
 
8
8
  describe "#add" do
9
9
 
10
10
  it "should log that the stub has been registered" do
11
- stub = double(Http::Stub::Stub, to_s: "Stub as String")
11
+ stub = double(HttpStub::Stub, to_s: "Stub as String")
12
12
  logger.should_receive(:info).with(/Stub as String/)
13
13
 
14
14
  registry.add(stub, request)
@@ -21,7 +21,7 @@ describe Http::Stub::Registry do
21
21
  describe "when multiple stubs have been registered" do
22
22
 
23
23
  let(:stubs) do
24
- (1..3).map { |i| double("#{Http::Stub::Stub}#{i}", :stubs? => false) }
24
+ (1..3).map { |i| double("#{HttpStub::Stub}#{i}", :stubs? => false) }
25
25
  end
26
26
 
27
27
  before(:each) do
@@ -78,8 +78,8 @@ describe Http::Stub::Registry do
78
78
 
79
79
  end
80
80
 
81
- it "it should log that a stub is being found" do
82
- logger.should_receive(:info).with(/Request as String/)
81
+ it "it should log stub discovery diagnostics that includes the complete details of the request" do
82
+ logger.should_receive(:info).with(/Request inspect result/)
83
83
 
84
84
  registry.find_for(request)
85
85
  end
@@ -1,10 +1,10 @@
1
- describe Http::Stub::Server do
1
+ describe HttpStub::Server do
2
2
  include Rack::Test::Methods
3
3
 
4
- let(:app) { Http::Stub::Server.new }
4
+ let(:app) { HttpStub::Server.new }
5
5
 
6
- let(:registry) { double(Http::Stub::Registry).as_null_object }
7
- before(:each) { Http::Stub::Registry.stub!(:new).and_return(registry) }
6
+ let(:registry) { double(HttpStub::Registry).as_null_object }
7
+ before(:each) { HttpStub::Registry.stub!(:new).and_return(registry) }
8
8
 
9
9
  let(:response) { last_response }
10
10
  let(:response_body) { response.body.to_s }
@@ -12,8 +12,8 @@ describe Http::Stub::Server do
12
12
  describe "when a stub request is received" do
13
13
 
14
14
  it "should register a stub encapsulating the request" do
15
- stub = double(Http::Stub::Stub)
16
- Http::Stub::Stub.should_receive(:new).and_return(stub)
15
+ stub = double(HttpStub::Stub)
16
+ HttpStub::Stub.should_receive(:new).and_return(stub)
17
17
  registry.should_receive(:add).with(stub, anything)
18
18
 
19
19
  issue_stub_request
@@ -27,7 +27,7 @@ describe Http::Stub::Server do
27
27
 
28
28
  before(:each) do
29
29
  registry.stub!(:find_for).and_return(
30
- double(Http::Stub::Stub, response: double("StubResponse", status: 500, body: "Some text")))
30
+ double(HttpStub::Stub, response: double("StubResponse", status: 500, body: "Some text")))
31
31
  end
32
32
 
33
33
  it "should respond with the configured status" do
@@ -1,4 +1,4 @@
1
- describe Http::Stub::StartServerRakeTask do
1
+ describe HttpStub::StartServerRakeTask do
2
2
  include_context "server integration"
3
3
 
4
4
  describe("when the generated task is invoked") do
@@ -1,4 +1,4 @@
1
- describe Http::Stub::Stub do
1
+ describe HttpStub::Stub do
2
2
 
3
3
  let(:stub_uri) { "/a_path" }
4
4
  let(:stub_method) { "get" }
@@ -15,7 +15,7 @@ describe Http::Stub::Stub do
15
15
  }.to_json
16
16
  end
17
17
  let(:stub_request) { double("HttpRequest", :body => double("HttpRequestBody", :read => stub_body)) }
18
- let(:stub_instance) { Http::Stub::Stub.new(stub_request) }
18
+ let(:stub_instance) { HttpStub::Stub.new(stub_request) }
19
19
 
20
20
  describe "#stubs?" do
21
21
 
data/spec/spec_helper.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  require 'cover_me'
2
2
  require 'rack/test'
3
3
 
4
- require File.expand_path('../../lib/http/stub/start_server_rake_task', __FILE__)
4
+ require File.expand_path('../../lib/http_stub/start_server_rake_task', __FILE__)
5
5
  require File.expand_path('../../lib/http_stub', __FILE__)
6
6
 
7
7
  Dir[File.expand_path('../support/**/*.rb', __FILE__)].each { |file| require file }
@@ -1,4 +1,4 @@
1
- share_examples_for "server integration" do
1
+ shared_context "server integration" do
2
2
 
3
3
  FIVE_SECONDS = 5
4
4
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: http_stub
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.1.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2013-02-12 00:00:00.000000000 Z
13
+ date: 2013-02-20 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: sinatra
@@ -44,6 +44,102 @@ dependencies:
44
44
  - - ~>
45
45
  - !ruby/object:Gem::Version
46
46
  version: 1.1.0
47
+ - !ruby/object:Gem::Dependency
48
+ name: rack-test
49
+ requirement: !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: 0.6.2
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: !ruby/object:Gem::Requirement
58
+ none: false
59
+ requirements:
60
+ - - ~>
61
+ - !ruby/object:Gem::Version
62
+ version: 0.6.2
63
+ - !ruby/object:Gem::Dependency
64
+ name: rake
65
+ requirement: !ruby/object:Gem::Requirement
66
+ none: false
67
+ requirements:
68
+ - - ~>
69
+ - !ruby/object:Gem::Version
70
+ version: 10.0.3
71
+ type: :development
72
+ prerelease: false
73
+ version_requirements: !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ~>
77
+ - !ruby/object:Gem::Version
78
+ version: 10.0.3
79
+ - !ruby/object:Gem::Dependency
80
+ name: rspec
81
+ requirement: !ruby/object:Gem::Requirement
82
+ none: false
83
+ requirements:
84
+ - - ~>
85
+ - !ruby/object:Gem::Version
86
+ version: '2.12'
87
+ type: :development
88
+ prerelease: false
89
+ version_requirements: !ruby/object:Gem::Requirement
90
+ none: false
91
+ requirements:
92
+ - - ~>
93
+ - !ruby/object:Gem::Version
94
+ version: '2.12'
95
+ - !ruby/object:Gem::Dependency
96
+ name: cover_me
97
+ requirement: !ruby/object:Gem::Requirement
98
+ none: false
99
+ requirements:
100
+ - - ~>
101
+ - !ruby/object:Gem::Version
102
+ version: 1.2.0
103
+ type: :development
104
+ prerelease: false
105
+ version_requirements: !ruby/object:Gem::Requirement
106
+ none: false
107
+ requirements:
108
+ - - ~>
109
+ - !ruby/object:Gem::Version
110
+ version: 1.2.0
111
+ - !ruby/object:Gem::Dependency
112
+ name: flog
113
+ requirement: !ruby/object:Gem::Requirement
114
+ none: false
115
+ requirements:
116
+ - - ~>
117
+ - !ruby/object:Gem::Version
118
+ version: 3.2.2
119
+ type: :development
120
+ prerelease: false
121
+ version_requirements: !ruby/object:Gem::Requirement
122
+ none: false
123
+ requirements:
124
+ - - ~>
125
+ - !ruby/object:Gem::Version
126
+ version: 3.2.2
127
+ - !ruby/object:Gem::Dependency
128
+ name: travis-lint
129
+ requirement: !ruby/object:Gem::Requirement
130
+ none: false
131
+ requirements:
132
+ - - ~>
133
+ - !ruby/object:Gem::Version
134
+ version: 1.6.0
135
+ type: :development
136
+ prerelease: false
137
+ version_requirements: !ruby/object:Gem::Requirement
138
+ none: false
139
+ requirements:
140
+ - - ~>
141
+ - !ruby/object:Gem::Version
142
+ version: 1.6.0
47
143
  description: Configure server responses via requests to /stub. Intended as an acceptance
48
144
  / integration testing tool.
49
145
  email: matthew.ueckerman@myob.com
@@ -51,19 +147,19 @@ executables: []
51
147
  extensions: []
52
148
  extra_rdoc_files: []
53
149
  files:
54
- - ./lib/http/stub/client.rb
55
- - ./lib/http/stub/registry.rb
56
- - ./lib/http/stub/server.rb
57
- - ./lib/http/stub/start_server_rake_task.rb
58
- - ./lib/http/stub/stub.rb
59
- - ./lib/http/stub/version.rb
150
+ - ./lib/http_stub/client.rb
151
+ - ./lib/http_stub/registry.rb
152
+ - ./lib/http_stub/server.rb
153
+ - ./lib/http_stub/start_server_rake_task.rb
154
+ - ./lib/http_stub/stub.rb
155
+ - ./lib/http_stub/version.rb
60
156
  - ./lib/http_stub.rb
61
- - ./spec/curl_sample.txt
62
- - ./spec/lib/http/client_integration_spec.rb
63
- - ./spec/lib/http/registry_spec.rb
64
- - ./spec/lib/http/server_spec.rb
65
- - ./spec/lib/http/start_server_rake_task_integration_spec.rb
66
- - ./spec/lib/http/stub_spec.rb
157
+ - ./spec/curl_samples.txt
158
+ - ./spec/lib/http_stub/client_integration_spec.rb
159
+ - ./spec/lib/http_stub/registry_spec.rb
160
+ - ./spec/lib/http_stub/server_spec.rb
161
+ - ./spec/lib/http_stub/start_server_rake_task_integration_spec.rb
162
+ - ./spec/lib/http_stub/stub_spec.rb
67
163
  - ./spec/spec_helper.rb
68
164
  - ./spec/support/server_integration.rb
69
165
  homepage: http://github.com/MYOB-Technology/http_stub
@@ -87,19 +183,19 @@ required_rubygems_version: !ruby/object:Gem::Requirement
87
183
  version: '0'
88
184
  segments:
89
185
  - 0
90
- hash: 698355929090701443
186
+ hash: -2002962712402429402
91
187
  requirements: []
92
188
  rubyforge_project: http_stub
93
189
  rubygems_version: 1.8.25
94
190
  signing_key:
95
191
  specification_version: 3
96
- summary: A Http Server replaying configured stub responses
192
+ summary: A HTTP Server replaying configured stub responses
97
193
  test_files:
98
- - ./spec/curl_sample.txt
99
- - ./spec/lib/http/client_integration_spec.rb
100
- - ./spec/lib/http/registry_spec.rb
101
- - ./spec/lib/http/server_spec.rb
102
- - ./spec/lib/http/start_server_rake_task_integration_spec.rb
103
- - ./spec/lib/http/stub_spec.rb
194
+ - ./spec/curl_samples.txt
195
+ - ./spec/lib/http_stub/client_integration_spec.rb
196
+ - ./spec/lib/http_stub/registry_spec.rb
197
+ - ./spec/lib/http_stub/server_spec.rb
198
+ - ./spec/lib/http_stub/start_server_rake_task_integration_spec.rb
199
+ - ./spec/lib/http_stub/stub_spec.rb
104
200
  - ./spec/spec_helper.rb
105
201
  - ./spec/support/server_integration.rb
@@ -1,60 +0,0 @@
1
- module Http
2
- module Stub
3
- module Client
4
-
5
- def self.included(mod)
6
- mod.extend(Http::Stub::Client::ClassMethods)
7
- mod.send(:include, Http::Stub::Client::InstanceMethods)
8
- end
9
-
10
- module ClassMethods
11
-
12
- attr_reader :host_value, :port_value
13
-
14
- def host(host)
15
- @host_value = host
16
- end
17
-
18
- def port(port)
19
- @port_value = port
20
- end
21
-
22
- end
23
-
24
- module InstanceMethods
25
-
26
- def stub!(uri, options)
27
- response_options = options[:response]
28
- request = Net::HTTP::Post.new("/stub")
29
- request.content_type = "application/json"
30
- request.body = {
31
- "uri" => uri,
32
- "method" => options[:method],
33
- "response" => {
34
- "status" => response_options[:status] || "200",
35
- "body" => response_options[:body]
36
- }
37
- }.to_json
38
- response = submit(request)
39
- raise "Unable to stub request: #{response.message}" unless response.code == "200"
40
- end
41
-
42
- alias_method :stub_response!, :stub!
43
-
44
- def clear!
45
- request = Net::HTTP::Delete.new("/stubs")
46
- response = submit(request)
47
- raise "Unable to clear stubs: #{response.message}" unless response.code == "200"
48
- end
49
-
50
- private
51
-
52
- def submit(request)
53
- Net::HTTP.new(self.class.host_value, self.class.port_value).start { |http| http.request(request) }
54
- end
55
-
56
- end
57
-
58
- end
59
- end
60
- end
@@ -1,28 +0,0 @@
1
- module Http
2
- module Stub
3
-
4
- class Registry
5
-
6
- def initialize
7
- @stubs = []
8
- end
9
-
10
- def add(stub, request)
11
- @stubs.unshift(stub)
12
- request.logger.info "Stub registered: #{stub}"
13
- end
14
-
15
- def find_for(request)
16
- request.logger.info "Finding stub fulfilling: #{request}"
17
- @stubs.find { |stub| stub.stubs?(request) }
18
- end
19
-
20
- def clear(request)
21
- request.logger.info "Clearing stubs"
22
- @stubs.clear
23
- end
24
-
25
- end
26
-
27
- end
28
- end
@@ -1,58 +0,0 @@
1
- module Http
2
- module Stub
3
-
4
- class Server < ::Sinatra::Base
5
-
6
- enable :dump_errors, :logging
7
-
8
- def initialize
9
- super()
10
- @registry = Http::Stub::Registry.new
11
- end
12
-
13
- private
14
-
15
- SUPPORTED_REQUEST_TYPES = [:get, :post, :put, :delete, :patch, :options].freeze
16
-
17
- def self.any_request_type(path, opts={}, &block)
18
- SUPPORTED_REQUEST_TYPES.each { |type| self.send(type, path, opts, &block) }
19
- end
20
-
21
- public
22
-
23
- # Sample request body:
24
- # {
25
- # "uri": "/some/path",
26
- # "method": "get",
27
- # "parameters": {
28
- # "key": "value",
29
- # ...
30
- # },
31
- # "response": {
32
- # "status": "200",
33
- # "body": "Hello World"
34
- # }
35
- # }
36
- post "/stub" do
37
- @registry.add(Http::Stub::Stub.new(request), request)
38
- halt 200
39
- end
40
-
41
- delete "/stubs" do
42
- @registry.clear(request)
43
- halt 200
44
- end
45
-
46
- any_request_type(//) { handle_stub_request }
47
-
48
- private
49
-
50
- def handle_stub_request
51
- stub = @registry.find_for(request)
52
- stub ? halt(stub.response.status, stub.response.body) : halt(404)
53
- end
54
-
55
- end
56
-
57
- end
58
- end
@@ -1,22 +0,0 @@
1
- require File.expand_path('../../../http_stub', __FILE__)
2
- require 'rake/tasklib' unless defined?(::Rake::TaskLib)
3
-
4
- module Http
5
- module Stub
6
-
7
- class StartServerRakeTask < ::Rake::TaskLib
8
-
9
- def initialize(options)
10
- desc "Starts stub #{options[:name]}"
11
- task "start_#{options[:name]}" do
12
- Http::Stub::Server.instance_eval do
13
- set :port, options[:port]
14
- run!
15
- end
16
- end
17
- end
18
-
19
- end
20
-
21
- end
22
- end
@@ -1,32 +0,0 @@
1
- module Http
2
- module Stub
3
- class Stub
4
-
5
- Response = ImmutableStruct.new(:status, :body)
6
-
7
- attr_reader :response
8
-
9
- def initialize(request)
10
- @data = JSON.parse(request.body.read)
11
- @response = Response.new(status: @data["response"]["status"], body: @data["response"]["body"])
12
- end
13
-
14
- def stubs?(request)
15
- @data["uri"] == request.path_info &&
16
- @data["method"].downcase == request.request_method.downcase &&
17
- parameters == request.params
18
- end
19
-
20
- def to_s
21
- @data.to_s
22
- end
23
-
24
- private
25
-
26
- def parameters
27
- @data["parameters"] || {}
28
- end
29
-
30
- end
31
- end
32
- end
@@ -1,5 +0,0 @@
1
- module Http
2
- module Stub
3
- VERSION = "0.0.4"
4
- end
5
- end
data/spec/curl_sample.txt DELETED
@@ -1 +0,0 @@
1
- curl -v -H "Accept: application/json" -H "Content-type: application/json" -X POST -d '{"uri": "/test", "method": "get", "response": {"status":"200", "body":"Foo"}}' http://localhost:8001/stub