Schmock 0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README +43 -0
- data/lib/schmock.rb +85 -0
- data/test/schmock_test.rb +66 -0
- metadata +41 -0
data/README
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
Schmock is a simple mock objects library that takes inspiration from flexmock and jmock.
|
|
2
|
+
|
|
3
|
+
The big difference between schmock and flexmock is that schmock can verify the inputs to methods called.
|
|
4
|
+
|
|
5
|
+
A simple example (pinched from the flexmock documentation!)
|
|
6
|
+
|
|
7
|
+
We have a data acquisition class (TemperatureSampler) that reads a temperature sensor and returns the highest of a number of measurements. We don’t have a real temperature to use for testing, so we mock one up with a mock object that responds to the read_temperature message.
|
|
8
|
+
|
|
9
|
+
Here’s the complete example:
|
|
10
|
+
|
|
11
|
+
class TemperatureSampler
|
|
12
|
+
def initialize(sensor)
|
|
13
|
+
@sensor = sensor
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def highest_temp(number_of_readings = 6)
|
|
17
|
+
total = @sensor.last_readings(number_of_readings).inject { |i,s| i+s }
|
|
18
|
+
return total / number_of_readings
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
class TestTemperatureSampler < Test::Unit::TestCase
|
|
24
|
+
|
|
25
|
+
def setup
|
|
26
|
+
@sensor = SchMock.new
|
|
27
|
+
@sampler = TemperatureSampler.new(@sensor)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def test_default_highest_temperature_considers_6_measurements
|
|
31
|
+
readings = [10, 12, 14, 13, 23, 42]
|
|
32
|
+
@sensor.__expects(:last_readings).with(6).returns(readings)
|
|
33
|
+
assert_equal 19, @sampler.highest_temp
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def test_can_vary_number_of_measurements
|
|
37
|
+
readings = [11,12,13]
|
|
38
|
+
@sensor.__expects(:last_readings).with(3).returns(readings)
|
|
39
|
+
assert_equal 12, @sampler.highest_temp(3)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
More examples can be found in the unit tests
|
data/lib/schmock.rb
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
require 'test/unit'
|
|
2
|
+
|
|
3
|
+
class SchMock
|
|
4
|
+
|
|
5
|
+
def initialize
|
|
6
|
+
@expectations = Hash.new
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def __expects(sym)
|
|
10
|
+
@expectations[sym] = SchMockExpectation.new
|
|
11
|
+
@expectations[sym]
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def __verify
|
|
15
|
+
@expectations.keys.each do |method|
|
|
16
|
+
@expectations[method].verify(method.to_s)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def ignore_missing
|
|
21
|
+
@ignore_missing = true
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def method_missing(sym, *args, &block)
|
|
25
|
+
if expectation = @expectations[sym]
|
|
26
|
+
expectation.verify_call(sym.to_s,args,block)
|
|
27
|
+
else
|
|
28
|
+
begin
|
|
29
|
+
super(sym, *args, &block) unless @ignore_missing
|
|
30
|
+
rescue NoMethodError
|
|
31
|
+
raise Test::Unit::AssertionFailedError, "Unexpected method "+sym.to_s+" called."
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
class SchMockExpectation
|
|
38
|
+
include Test::Unit::Assertions
|
|
39
|
+
|
|
40
|
+
def verify(message)
|
|
41
|
+
assert_equal @expected_call_count, @call_count, message+": Expected #{@expected_call_count} calls, got #{@call_count} calls"
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def verify_call(message,args,block)
|
|
45
|
+
assert_equal @expected_params, args, message+": Parameter mismatch"
|
|
46
|
+
args << block unless block.nil?
|
|
47
|
+
@call_count = @call_count + 1
|
|
48
|
+
@block.call(*args)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def initialize
|
|
52
|
+
@block = proc {}
|
|
53
|
+
@expected_call_count = 1
|
|
54
|
+
@call_count = 0
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def with(*args)
|
|
58
|
+
@expected_params = args
|
|
59
|
+
self
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def at_least_once
|
|
63
|
+
self
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def never
|
|
67
|
+
@expected_call_count = 0
|
|
68
|
+
self
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def twice
|
|
72
|
+
@expected_call_count = 2
|
|
73
|
+
self
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def returns(value=nil,&block)
|
|
77
|
+
if (block_given?)
|
|
78
|
+
@block = block
|
|
79
|
+
else
|
|
80
|
+
@block = proc { value }
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
require File.dirname(__FILE__) + '/../lib/schmock.rb'
|
|
2
|
+
|
|
3
|
+
class SchMockTest < Test::Unit::TestCase
|
|
4
|
+
|
|
5
|
+
def test_should_allow_block_to_calculate_return_values
|
|
6
|
+
mock = SchMock.new
|
|
7
|
+
mock.__expects(:random_call).with("a","b","c").returns { |a,b,c|
|
|
8
|
+
c+b+a
|
|
9
|
+
}
|
|
10
|
+
assert_equal "cba",mock.random_call("a","b","c")
|
|
11
|
+
mock.__verify
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def test_should_allow_parameter_as_return_value
|
|
16
|
+
mock = SchMock.new
|
|
17
|
+
mock.__expects(:random_call).with("a","b","c").returns("booh")
|
|
18
|
+
assert_equal "booh",mock.random_call("a","b","c")
|
|
19
|
+
mock.__verify
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def test_return_nil_if_no_return_value_set
|
|
23
|
+
mock = SchMock.new
|
|
24
|
+
mock.__expects(:random_call).with("a","b","c")
|
|
25
|
+
assert_nil mock.random_call("a","b","c")
|
|
26
|
+
mock.__verify
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def test_should_test_multiple_calls_to_method_with_same_parameters
|
|
30
|
+
mock = SchMock.new
|
|
31
|
+
mock.__expects(:random_call).twice.with("a","b","c")
|
|
32
|
+
mock.random_call("a","b","c")
|
|
33
|
+
mock.random_call("a","b","c")
|
|
34
|
+
mock.__verify
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def test_should_raise_exception_if_parameters_dont_match_when_method_called
|
|
38
|
+
mock = SchMock.new
|
|
39
|
+
mock.__expects(:random_call).with("a","b","c").returns("booh")
|
|
40
|
+
assert_raise(Test::Unit::AssertionFailedError) {
|
|
41
|
+
mock.random_call("a","d","c")
|
|
42
|
+
}
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def test_should_fail_if_unexpected_method_called
|
|
46
|
+
mock = SchMock.new
|
|
47
|
+
assert_raise(Test::Unit::AssertionFailedError) {
|
|
48
|
+
mock.random_call("a","d","c")
|
|
49
|
+
}
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def test_should_allow_unexpected_methods_if_ignore_missing_set
|
|
53
|
+
mock = SchMock.new
|
|
54
|
+
mock.ignore_missing
|
|
55
|
+
mock.random_call("a","d","c")
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def test_should_raise_exception_on_verify_if_call_counts_not_as_expected
|
|
59
|
+
mock = SchMock.new
|
|
60
|
+
mock.__expects(:random_call).twice.with("a","b","c").returns("booh")
|
|
61
|
+
mock.random_call("a","b","c")
|
|
62
|
+
assert_raise(Test::Unit::AssertionFailedError) {
|
|
63
|
+
mock.__verify
|
|
64
|
+
}
|
|
65
|
+
end
|
|
66
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
rubygems_version: 0.8.10
|
|
3
|
+
specification_version: 1
|
|
4
|
+
name: Schmock
|
|
5
|
+
version: !ruby/object:Gem::Version
|
|
6
|
+
version: "0.9"
|
|
7
|
+
date: 2005-06-26
|
|
8
|
+
summary: Simple mock objects
|
|
9
|
+
require_paths:
|
|
10
|
+
- lib
|
|
11
|
+
email: ben@revieworld.com
|
|
12
|
+
homepage:
|
|
13
|
+
rubyforge_project:
|
|
14
|
+
description:
|
|
15
|
+
autorequire: schmock
|
|
16
|
+
default_executable:
|
|
17
|
+
bindir: bin
|
|
18
|
+
has_rdoc: true
|
|
19
|
+
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
|
20
|
+
requirements:
|
|
21
|
+
-
|
|
22
|
+
- ">"
|
|
23
|
+
- !ruby/object:Gem::Version
|
|
24
|
+
version: 0.0.0
|
|
25
|
+
version:
|
|
26
|
+
platform: ruby
|
|
27
|
+
authors:
|
|
28
|
+
- Ben Griffiths
|
|
29
|
+
files:
|
|
30
|
+
- lib/schmock.rb
|
|
31
|
+
- test/schmock_test.rb
|
|
32
|
+
- README
|
|
33
|
+
test_files:
|
|
34
|
+
- test/schmock_test.rb
|
|
35
|
+
rdoc_options: []
|
|
36
|
+
extra_rdoc_files:
|
|
37
|
+
- README
|
|
38
|
+
executables: []
|
|
39
|
+
extensions: []
|
|
40
|
+
requirements: []
|
|
41
|
+
dependencies: []
|