hardmock 1.1.0
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/CHANGES +8 -0
- data/LICENSE +7 -0
- data/README +48 -0
- data/Rakefile +93 -0
- data/lib/hardmock.rb +634 -0
- data/lib/method_cleanout.rb +14 -0
- data/test/functional/assert_error_test.rb +52 -0
- data/test/functional/auto_verify_test.rb +192 -0
- data/test/functional/direct_mock_usage_test.rb +396 -0
- data/test/functional/hardmock_test.rb +371 -0
- data/test/test_helper.rb +23 -0
- data/test/unit/expectation_builder_test.rb +18 -0
- data/test/unit/expector_test.rb +54 -0
- data/test/unit/method_cleanout_test.rb +35 -0
- data/test/unit/mock_control_test.rb +172 -0
- data/test/unit/mock_test.rb +275 -0
- data/test/unit/simple_expectation_test.rb +345 -0
- data/test/unit/trapper_test.rb +60 -0
- data/test/unit/verify_error_test.rb +34 -0
- metadata +81 -0
@@ -0,0 +1,275 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + "/../test_helper")
|
2
|
+
require 'hardmock'
|
3
|
+
|
4
|
+
class MockTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
def test_build_with_control
|
7
|
+
mc1 = MockControl.new
|
8
|
+
mock = Mock.new('hi', mc1)
|
9
|
+
assert_equal 'hi', mock._name, "Wrong name"
|
10
|
+
assert_same mc1, mock._control, "Wrong contol"
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_basics
|
14
|
+
mock = Mock.new('a name')
|
15
|
+
assert_equal 'a name', mock._name, "Wrong name for mock"
|
16
|
+
assert_not_nil mock._control, "Nil control in mock"
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_expects
|
20
|
+
mock = Mock.new('order')
|
21
|
+
control = mock._control
|
22
|
+
assert control.happy?, "Mock should start out satisfied"
|
23
|
+
|
24
|
+
mock.expects.absorb_something(:location, 'garbage')
|
25
|
+
assert !control.happy?, "mock control should be unhappy"
|
26
|
+
|
27
|
+
# Do the call
|
28
|
+
mock.absorb_something(:location, 'garbage')
|
29
|
+
assert control.happy?, "mock control should be happy again"
|
30
|
+
|
31
|
+
# Verify
|
32
|
+
assert_nothing_raised Exception do
|
33
|
+
mock._verify
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_expects_using_arguments_for_method_and_arguments
|
38
|
+
mock = Mock.new('order')
|
39
|
+
mock.expects(:absorb_something, :location, 'garbage')
|
40
|
+
mock.absorb_something(:location, 'garbage')
|
41
|
+
mock._verify
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_expects_using_arguments_for_method_and_arguments_with_block
|
45
|
+
mock = Mock.new('order')
|
46
|
+
mock.expects(:absorb_something, :location, 'garbage') { |a,b,block|
|
47
|
+
assert_equal :location, a, "Wrong 'a' argument"
|
48
|
+
assert_equal 'garbage', b, "Wrong 'b' argument"
|
49
|
+
assert_equal 'innards', block.call, "Wrong block"
|
50
|
+
}
|
51
|
+
mock.absorb_something(:location, 'garbage') do "innards" end
|
52
|
+
mock._verify
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_expects_using_string_method_name
|
56
|
+
mock = Mock.new('order')
|
57
|
+
mock.expects('absorb_something', :location, 'garbage')
|
58
|
+
mock.absorb_something(:location, 'garbage')
|
59
|
+
mock._verify
|
60
|
+
end
|
61
|
+
|
62
|
+
|
63
|
+
def test_expects_assignment
|
64
|
+
mock = Mock.new('order')
|
65
|
+
mock.expects.account_number = 1234
|
66
|
+
|
67
|
+
mock.account_number = 1234
|
68
|
+
|
69
|
+
mock._verify
|
70
|
+
end
|
71
|
+
|
72
|
+
def test_expects_assigment_using_arguments_for_method_and_arguments
|
73
|
+
mock = Mock.new('order')
|
74
|
+
mock.expects(:account_number=, 1234)
|
75
|
+
mock.account_number = 1234
|
76
|
+
mock._verify
|
77
|
+
end
|
78
|
+
|
79
|
+
def test_expects_assigment_using_string_method_name
|
80
|
+
mock = Mock.new('order')
|
81
|
+
mock.expects('account_number=', 1234)
|
82
|
+
mock.account_number = 1234
|
83
|
+
mock._verify
|
84
|
+
end
|
85
|
+
|
86
|
+
def test_expects_assignment_and_return_is_overruled_by_ruby_syntax
|
87
|
+
# Prove that we can set up a return but that it doesn't mean much,
|
88
|
+
# because ruby's parser will 'do the right thing' as regards semantic
|
89
|
+
# values for assignment. (That is, the rvalue of the assignment)
|
90
|
+
mock = Mock.new('order')
|
91
|
+
mock.expects(:account_number=, 1234).returns "gold"
|
92
|
+
got = mock.account_number = 1234
|
93
|
+
mock._verify
|
94
|
+
assert_equal 1234, got, "Expected rvalue"
|
95
|
+
end
|
96
|
+
|
97
|
+
def test_expects_assignment_and_raise
|
98
|
+
mock = Mock.new('order')
|
99
|
+
mock.expects(:account_number=, 1234).raises StandardError.new("kaboom")
|
100
|
+
err = assert_raise StandardError do
|
101
|
+
mock.account_number = 1234
|
102
|
+
end
|
103
|
+
assert_match(/kaboom/i, err.message)
|
104
|
+
mock._verify
|
105
|
+
end
|
106
|
+
|
107
|
+
|
108
|
+
def test_expects_multiple
|
109
|
+
mock = Mock.new('order')
|
110
|
+
control = mock._control
|
111
|
+
|
112
|
+
assert control.happy?
|
113
|
+
|
114
|
+
mock.expects.one_thing :hi, { :goose => 'neck' }
|
115
|
+
mock.expects.another 5,6,7
|
116
|
+
assert !control.happy?
|
117
|
+
|
118
|
+
mock.one_thing :hi, { :goose => 'neck' }
|
119
|
+
assert !control.happy?
|
120
|
+
|
121
|
+
mock.another 5,6,7
|
122
|
+
assert control.happy?
|
123
|
+
end
|
124
|
+
|
125
|
+
def test_surprise_call
|
126
|
+
mock = Mock.new('order')
|
127
|
+
err = assert_raise ExpectationError do
|
128
|
+
mock.uh_oh
|
129
|
+
end
|
130
|
+
assert_match(/surprise/i, err.message)
|
131
|
+
assert_match(/uh_oh/i, err.message)
|
132
|
+
|
133
|
+
err = assert_raise ExpectationError do
|
134
|
+
mock.whoa :horse
|
135
|
+
end
|
136
|
+
assert_match(/surprise/i, err.message)
|
137
|
+
assert_match(/order\.whoa\(:horse\)/i, err.message)
|
138
|
+
end
|
139
|
+
|
140
|
+
def test_wrong_call
|
141
|
+
mock = Mock.new('order')
|
142
|
+
mock.expects.pig 'arse'
|
143
|
+
err = assert_raise ExpectationError do
|
144
|
+
mock.whoa :horse
|
145
|
+
end
|
146
|
+
assert_match(/wrong method/i, err.message)
|
147
|
+
assert_match(/order\.whoa\(:horse\)/i, err.message)
|
148
|
+
assert_match(/order\.pig\("arse"\)/i, err.message)
|
149
|
+
end
|
150
|
+
|
151
|
+
def test_wrong_arguments
|
152
|
+
mock = Mock.new('order')
|
153
|
+
mock.expects.go_fast(:a, 1, 'three')
|
154
|
+
|
155
|
+
err = assert_raise ExpectationError do
|
156
|
+
mock.go_fast :a, 1, 'not right'
|
157
|
+
end
|
158
|
+
assert_match(/wrong argument/i, err.message)
|
159
|
+
assert_match(/order\.go_fast\(:a, 1, "three"\)/i, err.message)
|
160
|
+
assert_match(/order\.go_fast\(:a, 1, "not right"\)/i, err.message)
|
161
|
+
end
|
162
|
+
|
163
|
+
def test_expects_and_return
|
164
|
+
mock = Mock.new('order')
|
165
|
+
mock.expects.delivery_date.returns Date.today
|
166
|
+
assert_equal Date.today, mock.delivery_date
|
167
|
+
mock._verify
|
168
|
+
end
|
169
|
+
|
170
|
+
def test_expects_and_return_with_arguments
|
171
|
+
mock = Mock.new('order')
|
172
|
+
mock.expects.delivery_date(:arf,14).returns(Date.today)
|
173
|
+
assert_equal Date.today, mock.delivery_date(:arf,14)
|
174
|
+
mock._verify
|
175
|
+
end
|
176
|
+
|
177
|
+
def test_expects_and_raise
|
178
|
+
mock = Mock.new('order')
|
179
|
+
mock.expects.delivery_date.raises StandardError.new("bloof")
|
180
|
+
|
181
|
+
err = assert_raise StandardError do
|
182
|
+
mock.delivery_date
|
183
|
+
end
|
184
|
+
assert_match(/bloof/i, err.message)
|
185
|
+
|
186
|
+
mock._verify
|
187
|
+
|
188
|
+
# Try convenience argument String
|
189
|
+
mock.expects.pow.raises "hell"
|
190
|
+
err = assert_raise RuntimeError do
|
191
|
+
mock.pow
|
192
|
+
end
|
193
|
+
assert_match(/hell/i, err.message)
|
194
|
+
|
195
|
+
mock._verify
|
196
|
+
|
197
|
+
# Try convenience argument nothing
|
198
|
+
mock.expects.pow.raises
|
199
|
+
err = assert_raise RuntimeError do
|
200
|
+
mock.pow
|
201
|
+
end
|
202
|
+
assert_match(/an error/i, err.message)
|
203
|
+
|
204
|
+
mock._verify
|
205
|
+
end
|
206
|
+
|
207
|
+
def test_expects_a_runtime_block
|
208
|
+
mock = Mock.new('order')
|
209
|
+
got_val = nil
|
210
|
+
|
211
|
+
mock.expects.when(:something) { |e,block|
|
212
|
+
got_val = block.call
|
213
|
+
}
|
214
|
+
|
215
|
+
mock.when :something do "hi there" end
|
216
|
+
|
217
|
+
assert_equal "hi there", got_val, "Expectation block not invoked"
|
218
|
+
mock._verify
|
219
|
+
end
|
220
|
+
|
221
|
+
def test_trap_block
|
222
|
+
mock = Mock.new('order')
|
223
|
+
exp = mock.trap.observe
|
224
|
+
|
225
|
+
# use it
|
226
|
+
mock.observe { "burp" }
|
227
|
+
|
228
|
+
assert_equal "burp", exp.block_value.call
|
229
|
+
end
|
230
|
+
|
231
|
+
def test_trap_arguments_and_block
|
232
|
+
mock = Mock.new('order')
|
233
|
+
exp = mock.trap.subscribe(:data_changed)
|
234
|
+
|
235
|
+
# use it
|
236
|
+
mock.subscribe(:data_changed) { "burp" }
|
237
|
+
assert_equal "burp", exp.block_value.call
|
238
|
+
mock._verify
|
239
|
+
end
|
240
|
+
|
241
|
+
def test_trap_arguments_and_block_wrong_num_args
|
242
|
+
mock = Mock.new('order')
|
243
|
+
exp = mock.trap.subscribe(:data_changed)
|
244
|
+
|
245
|
+
assert_raise ExpectationError do
|
246
|
+
mock.subscribe(:data_changed,1) { "burp" }
|
247
|
+
end
|
248
|
+
mock._verify
|
249
|
+
end
|
250
|
+
|
251
|
+
def test_trap_arguments_and_block_wrong_args
|
252
|
+
mock = Mock.new('order')
|
253
|
+
exp = mock.trap.subscribe(:data_changed)
|
254
|
+
|
255
|
+
assert_raise ExpectationError do
|
256
|
+
mock.subscribe("no good") { "burp" }
|
257
|
+
end
|
258
|
+
|
259
|
+
mock._verify
|
260
|
+
end
|
261
|
+
|
262
|
+
def test_trap_is_not_leniant_about_arguments
|
263
|
+
mock = Mock.new('order')
|
264
|
+
exp = mock.trap.subscribe
|
265
|
+
|
266
|
+
assert_raise ExpectationError do
|
267
|
+
mock.subscribe("no good") { "burp" }
|
268
|
+
end
|
269
|
+
|
270
|
+
mock._verify
|
271
|
+
end
|
272
|
+
|
273
|
+
|
274
|
+
|
275
|
+
end
|
@@ -0,0 +1,345 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + "/../test_helper")
|
2
|
+
require 'hardmock'
|
3
|
+
|
4
|
+
class SimpleExpectationTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
def setup
|
7
|
+
@mock = TheMock.new
|
8
|
+
end
|
9
|
+
#
|
10
|
+
# HELPERS
|
11
|
+
#
|
12
|
+
|
13
|
+
class TheMock
|
14
|
+
def _name; 'the_mock'; end
|
15
|
+
end
|
16
|
+
class OtherMock
|
17
|
+
def _name; 'other_mock'; end
|
18
|
+
end
|
19
|
+
|
20
|
+
#
|
21
|
+
# TESTS
|
22
|
+
#
|
23
|
+
|
24
|
+
def test_to_s
|
25
|
+
ex = SimpleExpectation.new( :mock => @mock, :method => 'a_func', :arguments => [1, "two", :three, { :four => 4 }] )
|
26
|
+
assert_equal %|the_mock.a_func(1, "two", :three, {:four=>4})|, ex.to_s
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_apply_method_call
|
30
|
+
se = SimpleExpectation.new(:mock => @mock, :method => 'some_func',
|
31
|
+
:arguments => [1,'two',:three] )
|
32
|
+
|
33
|
+
# Try it good:
|
34
|
+
assert_nothing_raised ExpectationError do
|
35
|
+
se.apply_method_call( @mock, 'some_func', [1,'two',:three], nil )
|
36
|
+
end
|
37
|
+
|
38
|
+
# Bad func name:
|
39
|
+
err = assert_raise ExpectationError do
|
40
|
+
se.apply_method_call( @mock, 'wrong_func', [1,'two',:three], nil )
|
41
|
+
end
|
42
|
+
assert_match(/wrong method/i, err.message)
|
43
|
+
assert_match(/wrong_func/i, err.message)
|
44
|
+
assert_match(/[1, "two", :three]/i, err.message)
|
45
|
+
assert_match(/some_func/i, err.message)
|
46
|
+
assert_match(/the_mock/i, err.message)
|
47
|
+
|
48
|
+
# Wrong mock
|
49
|
+
err = assert_raise ExpectationError do
|
50
|
+
se.apply_method_call( OtherMock.new, 'some_func', [1,'two',:three], nil )
|
51
|
+
end
|
52
|
+
assert_match(/[1, "two", :three]/i, err.message)
|
53
|
+
assert_match(/some_func/i, err.message)
|
54
|
+
assert_match(/the_mock/i, err.message)
|
55
|
+
assert_match(/other_mock/i, err.message)
|
56
|
+
|
57
|
+
# Wrong args
|
58
|
+
err = assert_raise ExpectationError do
|
59
|
+
se.apply_method_call( @mock, 'some_func', [1,'two',:four], nil)
|
60
|
+
end
|
61
|
+
assert_match(/[1, "two", :three]/i, err.message)
|
62
|
+
assert_match(/[1, "two", :four]/i, err.message)
|
63
|
+
assert_match(/wrong arguments/i, err.message)
|
64
|
+
assert_match(/some_func/i, err.message)
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_apply_method_call_should_call_proc_when_given
|
68
|
+
# now with a proc
|
69
|
+
thinger = nil
|
70
|
+
the_proc = Proc.new { thinger = :shaq }
|
71
|
+
se = SimpleExpectation.new(:mock => @mock, :method => 'some_func',
|
72
|
+
:block => the_proc)
|
73
|
+
|
74
|
+
# Try it good:
|
75
|
+
assert_nil thinger
|
76
|
+
assert_nothing_raised ExpectationError do
|
77
|
+
se.apply_method_call(@mock, 'some_func', [], nil)
|
78
|
+
end
|
79
|
+
assert_equal :shaq, thinger, 'wheres shaq??'
|
80
|
+
end
|
81
|
+
|
82
|
+
def test_apply_method_call_passes_runtime_block_as_last_argument_to_expectation_block
|
83
|
+
|
84
|
+
passed_block = nil
|
85
|
+
exp_block_called = false
|
86
|
+
exp_block = Proc.new { |blk|
|
87
|
+
exp_block_called = true
|
88
|
+
passed_block = blk
|
89
|
+
}
|
90
|
+
|
91
|
+
se = SimpleExpectation.new(:mock => @mock, :method => 'some_func', :block => exp_block,
|
92
|
+
:arguments => [])
|
93
|
+
|
94
|
+
set_flag = false
|
95
|
+
runtime_block = Proc.new { set_flag = true }
|
96
|
+
|
97
|
+
assert_nil passed_block, "Passed block should be nil"
|
98
|
+
assert !set_flag, "set_flag should be off"
|
99
|
+
|
100
|
+
# Go
|
101
|
+
se.apply_method_call( @mock, 'some_func', [], runtime_block)
|
102
|
+
|
103
|
+
# Examine the passed block
|
104
|
+
assert exp_block_called, "Expectation block not called"
|
105
|
+
assert_not_nil passed_block, "Should have been passed a block"
|
106
|
+
assert !set_flag, "set_flag should still be off"
|
107
|
+
passed_block.call
|
108
|
+
assert set_flag, "set_flag should be on"
|
109
|
+
end
|
110
|
+
|
111
|
+
def test_apply_method_call_fails_when_theres_no_expectation_block_to_handle_the_runtime_block
|
112
|
+
se = SimpleExpectation.new(:mock => @mock, :method => 'some_func', :arguments => [])
|
113
|
+
runtime_block = Proc.new { set_flag = true }
|
114
|
+
err = assert_raise ExpectationError do
|
115
|
+
se.apply_method_call( @mock, 'some_func', [], runtime_block)
|
116
|
+
end
|
117
|
+
assert_match(/unexpected block/i, err.message)
|
118
|
+
assert_match(/the_mock.some_func()/i, err.message)
|
119
|
+
end
|
120
|
+
|
121
|
+
def test_returns
|
122
|
+
se = SimpleExpectation.new(:mock => @mock, :method => 'some_func',
|
123
|
+
:arguments => [1,'two',:three])
|
124
|
+
|
125
|
+
se.returns "A value"
|
126
|
+
|
127
|
+
assert_equal "A value", se.apply_method_call(@mock, 'some_func', [1,'two',:three], nil)
|
128
|
+
end
|
129
|
+
|
130
|
+
def test_apply_method_call_captures_block_value
|
131
|
+
the_proc = lambda { "in the block" }
|
132
|
+
se = SimpleExpectation.new(:mock => @mock, :method => 'do_it', :arguments => [], :block => the_proc)
|
133
|
+
|
134
|
+
assert_nil se.block_value, "Block value starts out nil"
|
135
|
+
|
136
|
+
se.apply_method_call(@mock, 'do_it', [], nil)
|
137
|
+
|
138
|
+
assert_equal "in the block", se.block_value, "Block value not captured"
|
139
|
+
end
|
140
|
+
|
141
|
+
def test_trigger
|
142
|
+
# convenience method for block_value.call
|
143
|
+
target = false
|
144
|
+
inner_proc = lambda { target = true }
|
145
|
+
the_proc = lambda { inner_proc }
|
146
|
+
se = SimpleExpectation.new(:mock => @mock, :method => 'do_it', :arguments => [], :block => the_proc)
|
147
|
+
|
148
|
+
assert_nil se.block_value, "Block value starts out nil"
|
149
|
+
se.apply_method_call(@mock, 'do_it', [], nil)
|
150
|
+
assert_not_nil se.block_value, "Block value not set"
|
151
|
+
|
152
|
+
assert !target, "Target should still be false"
|
153
|
+
se.trigger
|
154
|
+
assert target, "Target not true!"
|
155
|
+
end
|
156
|
+
|
157
|
+
def test_trigger_with_arguments
|
158
|
+
# convenience method for block_value.call
|
159
|
+
target = nil
|
160
|
+
inner_proc = lambda { |one,two| target = [one,two] }
|
161
|
+
the_proc = lambda { inner_proc }
|
162
|
+
se = SimpleExpectation.new(:mock => @mock, :method => 'do_it', :arguments => [], :block => the_proc)
|
163
|
+
|
164
|
+
assert_nil se.block_value, "Block value starts out nil"
|
165
|
+
se.apply_method_call(@mock, 'do_it', [], nil)
|
166
|
+
assert_not_nil se.block_value, "Block value not set"
|
167
|
+
|
168
|
+
assert_nil target, "target should still be nil"
|
169
|
+
se.trigger 'cat','dog'
|
170
|
+
assert_equal ['cat','dog'], target
|
171
|
+
end
|
172
|
+
|
173
|
+
def test_trigger_nil_block_value
|
174
|
+
se = SimpleExpectation.new(:mock => @mock, :method => 'do_it', :arguments => [])
|
175
|
+
|
176
|
+
assert_nil se.block_value, "Block value starts out nil"
|
177
|
+
se.apply_method_call(@mock, 'do_it', [], nil)
|
178
|
+
assert_nil se.block_value, "Block value should still be nil"
|
179
|
+
|
180
|
+
err = assert_raise ExpectationError do
|
181
|
+
se.trigger
|
182
|
+
end
|
183
|
+
assert_match(/do_it/i, err.message)
|
184
|
+
assert_match(/block value/i, err.message)
|
185
|
+
end
|
186
|
+
|
187
|
+
def test_trigger_non_proc_block_value
|
188
|
+
the_block = lambda { "woops" }
|
189
|
+
se = SimpleExpectation.new(:mock => @mock, :method => 'do_it', :arguments => [], :block => the_block)
|
190
|
+
|
191
|
+
se.apply_method_call(@mock, 'do_it', [], nil)
|
192
|
+
assert_equal "woops", se.block_value
|
193
|
+
|
194
|
+
err = assert_raise ExpectationError do
|
195
|
+
se.trigger
|
196
|
+
end
|
197
|
+
assert_match(/do_it/i, err.message)
|
198
|
+
assert_match(/trigger/i, err.message)
|
199
|
+
assert_match(/woops/i, err.message)
|
200
|
+
end
|
201
|
+
|
202
|
+
|
203
|
+
|
204
|
+
def test_proc_used_for_return
|
205
|
+
the_proc = lambda { "in the block" }
|
206
|
+
se = SimpleExpectation.new(:mock => @mock, :method => 'do_it', :arguments => [], :block => the_proc)
|
207
|
+
|
208
|
+
assert_equal "in the block", se.apply_method_call(@mock, 'do_it', [], nil)
|
209
|
+
assert_equal "in the block", se.block_value, "Captured block value affected wrongly"
|
210
|
+
end
|
211
|
+
|
212
|
+
def test_explicit_return_overrides_proc_return
|
213
|
+
the_proc = lambda { "in the block" }
|
214
|
+
se = SimpleExpectation.new(:mock => @mock, :method => 'do_it', :arguments => [], :block => the_proc)
|
215
|
+
se.returns "the override"
|
216
|
+
assert_equal "the override", se.apply_method_call(@mock, 'do_it', [], nil)
|
217
|
+
assert_equal "in the block", se.block_value, "Captured block value affected wrongly"
|
218
|
+
end
|
219
|
+
|
220
|
+
def test_yields
|
221
|
+
se = SimpleExpectation.new(:mock => @mock, :method => 'each_bean', :arguments => [:side_slot] )
|
222
|
+
se.yields :bean1, :bean2
|
223
|
+
|
224
|
+
things = []
|
225
|
+
a_block = lambda { |thinger| things << thinger }
|
226
|
+
|
227
|
+
se.apply_method_call(@mock,'each_bean',[:side_slot],a_block)
|
228
|
+
assert_equal [:bean1,:bean2], things, "Wrong things"
|
229
|
+
end
|
230
|
+
|
231
|
+
def test_yields_block_takes_no_arguments
|
232
|
+
se = SimpleExpectation.new(:mock => @mock, :method => 'each_bean', :arguments => [:side_slot] )
|
233
|
+
se.yields
|
234
|
+
|
235
|
+
things = []
|
236
|
+
a_block = lambda { things << 'OOF' }
|
237
|
+
se.apply_method_call(@mock,'each_bean',[:side_slot],a_block)
|
238
|
+
assert_equal ['OOF'], things
|
239
|
+
end
|
240
|
+
|
241
|
+
def test_yields_params_to_block_takes_no_arguments
|
242
|
+
se = SimpleExpectation.new(:mock => @mock, :method => 'each_bean', :arguments => [:side_slot] )
|
243
|
+
se.yields :wont_fit
|
244
|
+
|
245
|
+
things = []
|
246
|
+
a_block = lambda { things << 'WUP' }
|
247
|
+
|
248
|
+
err = assert_raise ExpectationError do
|
249
|
+
se.apply_method_call(@mock,'each_bean',[:side_slot],a_block)
|
250
|
+
end
|
251
|
+
assert_match(/wont_fit/i, err.message)
|
252
|
+
assert_match(/arity -1/i, err.message)
|
253
|
+
assert_equal [], things, "Wrong things"
|
254
|
+
end
|
255
|
+
|
256
|
+
def test_yields_with_returns
|
257
|
+
se = SimpleExpectation.new(:mock => @mock, :method => 'each_bean', :arguments => [:side_slot] ,
|
258
|
+
:returns => 'the results')
|
259
|
+
|
260
|
+
exp = se.yields :bean1, :bean2
|
261
|
+
assert_same se, exp, "'yields' needs to return a reference to the expectation"
|
262
|
+
things = []
|
263
|
+
a_block = lambda { |thinger| things << thinger }
|
264
|
+
returned = se.apply_method_call(@mock,'each_bean',[:side_slot],a_block)
|
265
|
+
assert_equal [:bean1,:bean2], things, "Wrong things"
|
266
|
+
assert_equal 'the results', returned, "Wrong return value"
|
267
|
+
end
|
268
|
+
|
269
|
+
def test_yields_with_raises
|
270
|
+
se = SimpleExpectation.new(:mock => @mock, :method => 'each_bean', :arguments => [:side_slot],
|
271
|
+
:raises => RuntimeError.new("kerboom"))
|
272
|
+
|
273
|
+
exp = se.yields :bean1, :bean2
|
274
|
+
assert_same se, exp, "'yields' needs to return a reference to the expectation"
|
275
|
+
things = []
|
276
|
+
a_block = lambda { |thinger| things << thinger }
|
277
|
+
err = assert_raise RuntimeError do
|
278
|
+
se.apply_method_call(@mock,'each_bean',[:side_slot],a_block)
|
279
|
+
end
|
280
|
+
assert_match(/kerboom/i, err.message)
|
281
|
+
assert_equal [:bean1,:bean2], things, "Wrong things"
|
282
|
+
end
|
283
|
+
|
284
|
+
def test_yields_and_inner_block_explodes
|
285
|
+
se = SimpleExpectation.new(:mock => @mock, :method => 'each_bean', :arguments => [:side_slot])
|
286
|
+
|
287
|
+
exp = se.yields :bean1, :bean2
|
288
|
+
assert_same se, exp, "'yields' needs to return a reference to the expectation"
|
289
|
+
things = []
|
290
|
+
a_block = lambda { |thinger|
|
291
|
+
things << thinger
|
292
|
+
raise "nasty"
|
293
|
+
}
|
294
|
+
err = assert_raise RuntimeError do
|
295
|
+
se.apply_method_call(@mock,'each_bean',[:side_slot],a_block)
|
296
|
+
end
|
297
|
+
assert_match(/nasty/i, err.message)
|
298
|
+
assert_equal [:bean1], things, "Wrong things"
|
299
|
+
end
|
300
|
+
|
301
|
+
def test_yields_with_several_arrays
|
302
|
+
se = SimpleExpectation.new(:mock => @mock, :method => 'each_bean', :arguments => [:side_slot] )
|
303
|
+
se.yields ['a','b'], ['c','d']
|
304
|
+
|
305
|
+
things = []
|
306
|
+
a_block = lambda { |thinger| things << thinger }
|
307
|
+
|
308
|
+
se.apply_method_call(@mock,'each_bean',[:side_slot],a_block)
|
309
|
+
assert_equal [ ['a','b'], ['c','d'] ], things, "Wrong things"
|
310
|
+
end
|
311
|
+
|
312
|
+
def test_yields_tuples
|
313
|
+
se = SimpleExpectation.new(:mock => @mock, :method => 'each_bean', :arguments => [:side_slot] )
|
314
|
+
se.yields ['a','b','c'], ['d','e','f']
|
315
|
+
|
316
|
+
things = []
|
317
|
+
a_block = lambda { |left,mid,right|
|
318
|
+
things << { :left => left, :mid => mid, :right => right }
|
319
|
+
}
|
320
|
+
|
321
|
+
se.apply_method_call(@mock,'each_bean',[:side_slot],a_block)
|
322
|
+
assert_equal [
|
323
|
+
{:left => 'a', :mid => 'b', :right => 'c' },
|
324
|
+
{:left => 'd', :mid => 'e', :right => 'f' },
|
325
|
+
], things, "Wrong things"
|
326
|
+
end
|
327
|
+
|
328
|
+
def test_yields_tuples_size_mismatch
|
329
|
+
se = SimpleExpectation.new(:mock => @mock, :method => 'each_bean', :arguments => [:side_slot] )
|
330
|
+
se.yields ['a','b','c'], ['d','e','f']
|
331
|
+
|
332
|
+
things = []
|
333
|
+
a_block = lambda { |left,mid|
|
334
|
+
things << { :left => left, :mid => mid }
|
335
|
+
}
|
336
|
+
|
337
|
+
err = assert_raise ExpectationError do
|
338
|
+
se.apply_method_call(@mock,'each_bean',[:side_slot],a_block)
|
339
|
+
end
|
340
|
+
assert_match(/arity/i, err.message)
|
341
|
+
assert_match(/the_mock.each_bean/i, err.message)
|
342
|
+
assert_match(/"a", "b", "c"/i, err.message)
|
343
|
+
assert_equal [], things, "Wrong things"
|
344
|
+
end
|
345
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + "/../test_helper")
|
2
|
+
require 'hardmock'
|
3
|
+
|
4
|
+
class TrapperTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
def setup
|
7
|
+
@mock = Object.new
|
8
|
+
@mock_control = MyControl.new
|
9
|
+
@builder = ExpBuilder.new
|
10
|
+
@trapper = Trapper.new(@mock, @mock_control, @builder)
|
11
|
+
end
|
12
|
+
|
13
|
+
#
|
14
|
+
# HELPERS
|
15
|
+
#
|
16
|
+
|
17
|
+
class MyControl
|
18
|
+
attr_reader :added
|
19
|
+
def add_expectation(expectation)
|
20
|
+
@added ||= []
|
21
|
+
@added << expectation
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class ExpBuilder
|
26
|
+
attr_reader :options
|
27
|
+
def build_expectation(options)
|
28
|
+
@options = options
|
29
|
+
"dummy expectation"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
#
|
34
|
+
# TESTS
|
35
|
+
#
|
36
|
+
|
37
|
+
def test_method_missing
|
38
|
+
|
39
|
+
output = @trapper.change(:less)
|
40
|
+
|
41
|
+
assert_same @mock, @builder.options[:mock]
|
42
|
+
assert_equal :change, @builder.options[:method]
|
43
|
+
assert_equal [:less], @builder.options[:arguments]
|
44
|
+
assert_not_nil @builder.options[:block]
|
45
|
+
assert @builder.options[:suppress_arguments_to_block], ":suppress_arguments_to_block should be set"
|
46
|
+
assert_equal [ "dummy expectation" ], @mock_control.added,
|
47
|
+
"Wrong expectation added to control"
|
48
|
+
|
49
|
+
assert_equal "dummy expectation", output, "Expectation should have been returned"
|
50
|
+
|
51
|
+
# Examine the block. It should take one argument and simply return
|
52
|
+
# that argument. because of the 'suppress arguments to block'
|
53
|
+
# setting, the argument can only end up being a block, in practice.
|
54
|
+
trapper_block = @builder.options[:block]
|
55
|
+
assert_equal "the argument", trapper_block.call("the argument"),
|
56
|
+
"The block should merely return the passed argument"
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
end
|