mimic 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +20 -11
- data/Rakefile +4 -3
- data/lib/mimic.rb +7 -34
- data/lib/mimic/fake_host.rb +25 -35
- metadata +26 -16
data/README.md
CHANGED
@@ -8,17 +8,13 @@ There are already some good tools, like [FakeWeb](http://fakeweb.rubyforge.org/)
|
|
8
8
|
|
9
9
|
Mimic aims to make it possible to test your networking code without actually hitting the real services by starting up a real web server and responding to HTTP requests. This lets you test your application against canned responses in an as-close-to-the-real-thing-as-possible way.
|
10
10
|
|
11
|
-
Also, because Mimic
|
12
|
-
|
13
|
-
## How does it work?
|
14
|
-
|
15
|
-
Mimic's API is designed to be simple yet expressive. You simply register the host that you want to fake and then register any number of requests and responses. Mimic will then start an HTTP server (using Rack and WEBRick) on the specified port and add an entry to your hosts file (OSX and Linux only) for that host.
|
11
|
+
Also, because Mimic responds to real HTTP requests, it can be used when testing non-Ruby applications too.
|
16
12
|
|
17
13
|
## Examples
|
18
14
|
|
19
15
|
Registering to a single request stub:
|
20
16
|
|
21
|
-
Mimic.mimic
|
17
|
+
Mimic.mimic.get("/some/path").returning("hello world")
|
22
18
|
|
23
19
|
And the result, using RestClient:
|
24
20
|
|
@@ -26,18 +22,31 @@ And the result, using RestClient:
|
|
26
22
|
|
27
23
|
Registering multiple request stubs; note that you can stub the same path with different HTTP methods separately.
|
28
24
|
|
29
|
-
Mimic.mimic
|
25
|
+
Mimic.mimic do
|
30
26
|
get("/some/path").returning("Hello World", 200)
|
31
27
|
get("/some/other/path").returning("Redirecting...", 301, {"Location" => "somewhere else"})
|
32
28
|
post("/some/path").returning("Created!", 201)
|
33
29
|
end
|
34
30
|
|
35
|
-
|
36
|
-
|
37
|
-
|
31
|
+
You can even use Rack middlewares, e.g. to handle common testing scenarios such as authentication:
|
32
|
+
|
33
|
+
Mimic.mimic do
|
34
|
+
use Rack::Auth::Basic do |user, pass|
|
35
|
+
user == 'theuser' and pass == 'thepass'
|
36
|
+
end
|
37
|
+
|
38
|
+
get("/some/path")
|
39
|
+
end
|
40
|
+
|
41
|
+
Finally, because Mimic is built on top of Sinatra for the core request handling, you can create your stubbed requests like you would in any Sinatra app:
|
38
42
|
|
39
|
-
|
43
|
+
Mimic.mimic do
|
44
|
+
get "/some/path" do
|
45
|
+
[200, {}, "hello world"]
|
46
|
+
end
|
47
|
+
end
|
40
48
|
|
41
49
|
## License
|
42
50
|
|
43
51
|
As usual, the code is released under the MIT license which is included in the repository.
|
52
|
+
|
data/Rakefile
CHANGED
@@ -27,7 +27,7 @@ spec = Gem::Specification.new do |s|
|
|
27
27
|
|
28
28
|
# Change these as appropriate
|
29
29
|
s.name = "mimic"
|
30
|
-
s.version = "0.
|
30
|
+
s.version = "0.2.0"
|
31
31
|
s.summary = "A Ruby gem for faking external web services for testing"
|
32
32
|
s.author = "Luke Redpath"
|
33
33
|
s.email = "luke@lukeredpath.co.uk"
|
@@ -43,12 +43,13 @@ spec = Gem::Specification.new do |s|
|
|
43
43
|
|
44
44
|
# If you want to depend on other gems, add them here, along with any
|
45
45
|
# relevant versions
|
46
|
-
s.add_dependency("
|
47
|
-
s.add_dependency("
|
46
|
+
s.add_dependency("rack")
|
47
|
+
s.add_dependency("sinatra")
|
48
48
|
|
49
49
|
# If your tests use any gems, include them here
|
50
50
|
s.add_development_dependency("rspec")
|
51
51
|
s.add_development_dependency("cucumber")
|
52
|
+
s.add_development_dependency("mocha")
|
52
53
|
end
|
53
54
|
|
54
55
|
# This task actually builds the gem. We also regenerate a static
|
data/lib/mimic.rb
CHANGED
@@ -7,23 +7,17 @@ require 'logger'
|
|
7
7
|
module Mimic
|
8
8
|
MIMIC_DEFAULT_PORT = 11988
|
9
9
|
|
10
|
-
def self.mimic(
|
11
|
-
|
12
|
-
|
10
|
+
def self.mimic(options = {}, &block)
|
11
|
+
options = {:hostname => 'localhost', :port => MIMIC_DEFAULT_PORT}.merge(options)
|
12
|
+
|
13
|
+
FakeHost.new(options[:hostname]).tap do |host|
|
13
14
|
host.instance_eval(&block) if block_given?
|
14
|
-
Server.instance.serve(host, port)
|
15
|
+
Server.instance.serve(host, options[:port])
|
15
16
|
end
|
16
17
|
end
|
17
18
|
|
18
19
|
def self.cleanup!
|
19
20
|
Mimic::Server.instance.shutdown
|
20
|
-
registry.unregister_all_hosts
|
21
|
-
end
|
22
|
-
|
23
|
-
private
|
24
|
-
|
25
|
-
def self.registry
|
26
|
-
@registry ||= Registry.new
|
27
21
|
end
|
28
22
|
|
29
23
|
class Server
|
@@ -34,12 +28,11 @@ module Mimic
|
|
34
28
|
end
|
35
29
|
|
36
30
|
def serve(host_app, port)
|
37
|
-
webrick_logger = logger
|
38
31
|
@thread = Thread.fork do
|
39
32
|
Rack::Handler::WEBrick.run(host_app,
|
40
33
|
:Port => port,
|
41
|
-
:Logger =>
|
42
|
-
:AccessLog =>
|
34
|
+
:Logger => logger,
|
35
|
+
:AccessLog => logger
|
43
36
|
|
44
37
|
) { |server| @server = server }
|
45
38
|
end
|
@@ -52,24 +45,4 @@ module Mimic
|
|
52
45
|
end
|
53
46
|
end
|
54
47
|
end
|
55
|
-
|
56
|
-
class Registry
|
57
|
-
def initialize
|
58
|
-
@hosts = []
|
59
|
-
end
|
60
|
-
|
61
|
-
def register_host(host)
|
62
|
-
@hosts << host
|
63
|
-
Host.add(host.hostname)
|
64
|
-
end
|
65
|
-
|
66
|
-
def unregister_host(host)
|
67
|
-
@hosts.delete(host)
|
68
|
-
Host.delete(host.hostname)
|
69
|
-
end
|
70
|
-
|
71
|
-
def unregister_all_hosts
|
72
|
-
@hosts.each { |host| unregister_host(host) }
|
73
|
-
end
|
74
|
-
end
|
75
48
|
end
|
data/lib/mimic/fake_host.rb
CHANGED
@@ -1,11 +1,17 @@
|
|
1
|
+
require 'sinatra/base'
|
2
|
+
|
1
3
|
module Mimic
|
2
4
|
class FakeHost
|
3
5
|
attr_reader :hostname
|
4
6
|
|
5
|
-
def initialize(hostname
|
7
|
+
def initialize(hostname)
|
6
8
|
@hostname = hostname
|
7
|
-
@stubs =
|
8
|
-
@
|
9
|
+
@stubs = []
|
10
|
+
@app = Class.new(Sinatra::Base)
|
11
|
+
|
12
|
+
@app.not_found do
|
13
|
+
[404, {}, ""]
|
14
|
+
end
|
9
15
|
end
|
10
16
|
|
11
17
|
def get(path)
|
@@ -29,35 +35,32 @@ module Mimic
|
|
29
35
|
end
|
30
36
|
|
31
37
|
def call(env)
|
32
|
-
|
38
|
+
@stubs.each(&:build)
|
39
|
+
@app.call(env)
|
33
40
|
end
|
34
41
|
|
35
|
-
def
|
36
|
-
|
42
|
+
def method_missing(method, *args, &block)
|
43
|
+
@app.send(method, *args, &block)
|
37
44
|
end
|
38
45
|
|
39
46
|
private
|
40
47
|
|
41
|
-
def request(method, path)
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
end
|
49
|
-
|
50
|
-
def request_key(env)
|
51
|
-
request = Rack::Request.new(env)
|
52
|
-
StubbedRequest.key(request.request_method, request.path)
|
48
|
+
def request(method, path, &block)
|
49
|
+
if block_given?
|
50
|
+
@app.send(method.downcase, path, &block)
|
51
|
+
else
|
52
|
+
@stubs << StubbedRequest.new(@app, method, path)
|
53
|
+
@stubs.last
|
54
|
+
end
|
53
55
|
end
|
54
56
|
|
55
57
|
class StubbedRequest
|
56
|
-
def initialize(method, path)
|
58
|
+
def initialize(app, method, path)
|
57
59
|
@method, @path = method, path
|
58
60
|
@code = 200
|
59
61
|
@headers = {}
|
60
62
|
@body = ""
|
63
|
+
@app = app
|
61
64
|
end
|
62
65
|
|
63
66
|
def returning(body, code = 200, headers = {})
|
@@ -68,22 +71,9 @@ module Mimic
|
|
68
71
|
end
|
69
72
|
end
|
70
73
|
|
71
|
-
def
|
72
|
-
[@code, @headers, @body]
|
73
|
-
|
74
|
-
|
75
|
-
def key
|
76
|
-
self.class.key(@method, @path)
|
77
|
-
end
|
78
|
-
|
79
|
-
def self.key(method, path)
|
80
|
-
"#{method} #{path}"
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
class NotFoundResponseStrategy
|
85
|
-
def call(env)
|
86
|
-
[404, {}, ""]
|
74
|
+
def build
|
75
|
+
response = [@code, @headers, @body]
|
76
|
+
@app.send(@method.downcase, @path) { response }
|
87
77
|
end
|
88
78
|
end
|
89
79
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mimic
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 23
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
8
|
+
- 2
|
9
9
|
- 0
|
10
|
-
version: 0.
|
10
|
+
version: 0.2.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Luke Redpath
|
@@ -19,35 +19,31 @@ date: 2010-08-19 00:00:00 +01:00
|
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
22
|
-
name:
|
22
|
+
name: rack
|
23
23
|
prerelease: false
|
24
24
|
requirement: &id001 !ruby/object:Gem::Requirement
|
25
25
|
none: false
|
26
26
|
requirements:
|
27
|
-
- -
|
27
|
+
- - ">="
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
hash:
|
29
|
+
hash: 3
|
30
30
|
segments:
|
31
31
|
- 0
|
32
|
-
|
33
|
-
- 5
|
34
|
-
version: 0.2.5
|
32
|
+
version: "0"
|
35
33
|
type: :runtime
|
36
34
|
version_requirements: *id001
|
37
35
|
- !ruby/object:Gem::Dependency
|
38
|
-
name:
|
36
|
+
name: sinatra
|
39
37
|
prerelease: false
|
40
38
|
requirement: &id002 !ruby/object:Gem::Requirement
|
41
39
|
none: false
|
42
40
|
requirements:
|
43
|
-
- -
|
41
|
+
- - ">="
|
44
42
|
- !ruby/object:Gem::Version
|
45
|
-
hash:
|
43
|
+
hash: 3
|
46
44
|
segments:
|
47
|
-
-
|
48
|
-
|
49
|
-
- 1
|
50
|
-
version: 1.2.1
|
45
|
+
- 0
|
46
|
+
version: "0"
|
51
47
|
type: :runtime
|
52
48
|
version_requirements: *id002
|
53
49
|
- !ruby/object:Gem::Dependency
|
@@ -78,6 +74,20 @@ dependencies:
|
|
78
74
|
version: "0"
|
79
75
|
type: :development
|
80
76
|
version_requirements: *id004
|
77
|
+
- !ruby/object:Gem::Dependency
|
78
|
+
name: mocha
|
79
|
+
prerelease: false
|
80
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ">="
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
hash: 3
|
86
|
+
segments:
|
87
|
+
- 0
|
88
|
+
version: "0"
|
89
|
+
type: :development
|
90
|
+
version_requirements: *id005
|
81
91
|
description:
|
82
92
|
email: luke@lukeredpath.co.uk
|
83
93
|
executables: []
|