mock-server-thin 0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.markdown +45 -0
- data/lib/mock_server.rb +65 -0
- data/test/mock_server_test.rb +52 -0
- metadata +72 -0
data/README.markdown
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
# MockServer #
|
2
|
+
|
3
|
+
A quick way of mocking an external web service you want to consume.
|
4
|
+
|
5
|
+
## Usage ##
|
6
|
+
|
7
|
+
You're writing a feature that needs to connect to an external web service
|
8
|
+
(anything served by HTTP). You wonder how to test that. Your options
|
9
|
+
are to stub methods in Net::HTTP and equivalents, but by doing that you
|
10
|
+
are tying yourself to an implementation detail. The ideal thing to do
|
11
|
+
is to lay out an environment where your code can still run, connect to
|
12
|
+
a web server, send out requests and get responses back. Enter MockServer.
|
13
|
+
|
14
|
+
class RSSFeedTest < Test::Unit::TestCase
|
15
|
+
extend MockServer::Methods
|
16
|
+
|
17
|
+
mock_server {
|
18
|
+
get "/feed.xml" do
|
19
|
+
<<-EOS
|
20
|
+
<?xml version="1.0"?>
|
21
|
+
<rss version="2.0">
|
22
|
+
<channel>
|
23
|
+
<title>A mock website</title>
|
24
|
+
<link>http://example.com/</link>
|
25
|
+
</channel>
|
26
|
+
</rss>
|
27
|
+
EOS
|
28
|
+
end
|
29
|
+
}
|
30
|
+
|
31
|
+
def test_rss_feed
|
32
|
+
# YourAwesomeComponent should connect to http://localhost:4000.
|
33
|
+
# (you *are* putting those URLs in an environment-aware config file, right?)
|
34
|
+
|
35
|
+
posts = YourAwesomeComponent.load_posts
|
36
|
+
|
37
|
+
assert_equal "A mock website", post.first.channel.title
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
Yes, things happening inside the `mock_server` call are just a regular Sinatra application. w00t!
|
42
|
+
|
43
|
+
## License ##
|
44
|
+
|
45
|
+
MIT.
|
data/lib/mock_server.rb
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
require "sinatra/base"
|
2
|
+
require "logger"
|
3
|
+
|
4
|
+
class MockServer
|
5
|
+
class App < Sinatra::Base
|
6
|
+
use Rack::ShowExceptions
|
7
|
+
end
|
8
|
+
|
9
|
+
def initialize(app, port = 4000, &block)
|
10
|
+
@app = app
|
11
|
+
@port = port
|
12
|
+
end
|
13
|
+
|
14
|
+
def start
|
15
|
+
Thread.new do
|
16
|
+
with_quiet_logger do |logger|
|
17
|
+
Rack::Handler::Thin.run(@app, :Port => @port, :Logger => logger, :AccessLog => [])
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
wait_for_service("0.0.0.0", @port)
|
22
|
+
|
23
|
+
self
|
24
|
+
end
|
25
|
+
|
26
|
+
module Methods
|
27
|
+
def mock_server(*args, &block)
|
28
|
+
app = Class.new(Sinatra::Base)
|
29
|
+
app.class_eval(&block)
|
30
|
+
@server = MockServer.new(app, *args, &block).start
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
protected
|
35
|
+
def with_quiet_logger
|
36
|
+
io = File.open("/dev/null", "w")
|
37
|
+
yield(::Logger.new(io))
|
38
|
+
ensure
|
39
|
+
io.close
|
40
|
+
end
|
41
|
+
|
42
|
+
def listening?(host, port)
|
43
|
+
begin
|
44
|
+
socket = TCPSocket.new(host, port)
|
45
|
+
socket.close unless socket.nil?
|
46
|
+
true
|
47
|
+
rescue Errno::ECONNREFUSED,
|
48
|
+
Errno::EBADF, # Windows
|
49
|
+
Errno::EADDRNOTAVAIL # Windows
|
50
|
+
false
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def wait_for_service(host, port, timeout = 5)
|
55
|
+
start_time = Time.now
|
56
|
+
|
57
|
+
until listening?(host, port)
|
58
|
+
if timeout && (Time.now > (start_time + timeout))
|
59
|
+
raise SocketError.new("Socket did not open within #{timeout} seconds")
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
true
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "..", "lib", "mock_server"))
|
2
|
+
|
3
|
+
require "test/unit"
|
4
|
+
require "ruby-debug"
|
5
|
+
require "open-uri"
|
6
|
+
|
7
|
+
class HelloWorldSinatra < Sinatra::Base
|
8
|
+
get "/" do
|
9
|
+
"Hello"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class MockServerTest < Test::Unit::TestCase
|
14
|
+
def setup
|
15
|
+
@server = MockServer.new(HelloWorldSinatra)
|
16
|
+
@server.start
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_server
|
20
|
+
assert_equal "Hello", open("http://localhost:4000").read
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
HelloWorldRackBuilder = Rack::Builder.new do
|
25
|
+
run lambda {|env|
|
26
|
+
[200, {"Content-Type" => "text/plain", "Content-Length" => "7"}, ["Rackup!"]]
|
27
|
+
}
|
28
|
+
end
|
29
|
+
|
30
|
+
class MockServerRackBuilderTest < Test::Unit::TestCase
|
31
|
+
def setup
|
32
|
+
@server = MockServer.new(HelloWorldRackBuilder, 4001)
|
33
|
+
@server.start
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_server
|
37
|
+
assert_equal "Rackup!", open("http://localhost:4001").read
|
38
|
+
end end
|
39
|
+
|
40
|
+
class MockServerMethodsTest < Test::Unit::TestCase
|
41
|
+
extend MockServer::Methods
|
42
|
+
|
43
|
+
mock_server(4002) {
|
44
|
+
get "/" do
|
45
|
+
"Goodbye"
|
46
|
+
end
|
47
|
+
}
|
48
|
+
|
49
|
+
def test_server
|
50
|
+
assert_equal "Goodbye", open("http://localhost:4002").read
|
51
|
+
end
|
52
|
+
end
|
metadata
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mock-server-thin
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: '0.1'
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Damian Janowski
|
9
|
+
- Pablo Astigarraga
|
10
|
+
autorequire:
|
11
|
+
bindir: bin
|
12
|
+
cert_chain: []
|
13
|
+
date: 2011-11-18 00:00:00.000000000Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: sinatra
|
17
|
+
requirement: &2156746880 !ruby/object:Gem::Requirement
|
18
|
+
none: false
|
19
|
+
requirements:
|
20
|
+
- - ! '>='
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '0'
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: *2156746880
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: thin
|
28
|
+
requirement: &2156746000 !ruby/object:Gem::Requirement
|
29
|
+
none: false
|
30
|
+
requirements:
|
31
|
+
- - ! '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: *2156746000
|
37
|
+
description:
|
38
|
+
email:
|
39
|
+
- djanowski@dimaion.com
|
40
|
+
- pote@tardis.com.uy
|
41
|
+
executables: []
|
42
|
+
extensions: []
|
43
|
+
extra_rdoc_files: []
|
44
|
+
files:
|
45
|
+
- lib/mock_server.rb
|
46
|
+
- README.markdown
|
47
|
+
- test/mock_server_test.rb
|
48
|
+
homepage: http://github.com/pote/mock-server-thin
|
49
|
+
licenses: []
|
50
|
+
post_install_message:
|
51
|
+
rdoc_options: []
|
52
|
+
require_paths:
|
53
|
+
- lib
|
54
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
55
|
+
none: false
|
56
|
+
requirements:
|
57
|
+
- - ! '>='
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: '0'
|
60
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ! '>='
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '0'
|
66
|
+
requirements: []
|
67
|
+
rubyforge_project:
|
68
|
+
rubygems_version: 1.8.10
|
69
|
+
signing_key:
|
70
|
+
specification_version: 3
|
71
|
+
summary: A quick way of mocking an external web service you want to consume.
|
72
|
+
test_files: []
|