rspec-mocks 2.5.0 → 2.6.0.rc2
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/.travis.yml +7 -0
- data/Gemfile +13 -12
- data/Guardfile +3 -3
- data/README.md +2 -0
- data/features/.nav +4 -0
- data/features/Changelog.md +12 -0
- data/features/README.markdown +44 -4
- data/features/message_expectations/any_instance.feature +19 -0
- data/features/message_expectations/block_local_expectations.feature.pending +2 -2
- data/features/message_expectations/expect_message.feature +3 -3
- data/features/message_expectations/warn_when_expectation_is_set_on_nil.feature +3 -3
- data/features/method_stubs/README.md +32 -24
- data/features/method_stubs/any_instance.feature +23 -0
- data/features/method_stubs/as_null_object.feature +36 -0
- data/features/method_stubs/simple_return_value.feature +2 -2
- data/features/method_stubs/stub_chain.feature +13 -6
- data/features/method_stubs/stub_implementation.feature +1 -1
- data/features/method_stubs/to_ary.feature +45 -0
- data/features/outside_rspec/configuration.feature +3 -3
- data/features/outside_rspec/standalone.feature +2 -2
- data/features/step_definitions/additional_cli_steps.rb +4 -0
- data/features/support/env.rb +5 -1
- data/lib/rspec/mocks.rb +2 -1
- data/lib/rspec/mocks/any_instance.rb +246 -0
- data/lib/rspec/mocks/extensions/psych.rb +23 -0
- data/lib/rspec/mocks/framework.rb +1 -0
- data/lib/rspec/mocks/message_expectation.rb +7 -4
- data/lib/rspec/mocks/methods.rb +1 -1
- data/lib/rspec/mocks/mock.rb +2 -2
- data/lib/rspec/mocks/serialization.rb +5 -3
- data/lib/rspec/mocks/space.rb +1 -1
- data/lib/rspec/mocks/version.rb +1 -1
- data/spec/rspec/mocks/and_yield_spec.rb +3 -3
- data/spec/rspec/mocks/any_instance_spec.rb +578 -0
- data/spec/rspec/mocks/any_number_of_times_spec.rb +22 -28
- data/spec/rspec/mocks/at_least_spec.rb +6 -0
- data/spec/rspec/mocks/at_most_spec.rb +6 -0
- data/spec/rspec/mocks/bug_report_10263_spec.rb +12 -14
- data/spec/rspec/mocks/bug_report_7611_spec.rb +2 -4
- data/spec/rspec/mocks/failing_argument_matchers_spec.rb +45 -46
- data/spec/rspec/mocks/nil_expectation_warning_spec.rb +1 -2
- data/spec/rspec/mocks/passing_argument_matchers_spec.rb +119 -122
- data/spec/rspec/mocks/precise_counts_spec.rb +6 -0
- data/spec/rspec/mocks/serialization_spec.rb +21 -3
- data/spec/rspec/mocks/stub_chain_spec.rb +72 -37
- data/spec/rspec/mocks/stub_spec.rb +64 -61
- data/spec/rspec/mocks/to_ary_spec.rb +31 -0
- metadata +32 -15
- data/spec/rspec/mocks/bug_report_7805_spec.rb +0 -22
- data/spec/rspec/mocks/bug_report_8302_spec.rb +0 -26
data/lib/rspec/mocks/space.rb
CHANGED
data/lib/rspec/mocks/version.rb
CHANGED
@@ -0,0 +1,578 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module RSpec
|
4
|
+
module Mocks
|
5
|
+
describe "#any_instance" do
|
6
|
+
class CustomErrorForAnyInstanceSpec < StandardError;end
|
7
|
+
|
8
|
+
let(:klass) do
|
9
|
+
Class.new do
|
10
|
+
def existing_method; :existing_method_return_value; end
|
11
|
+
def another_existing_method; 4; end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
let(:existing_method_return_value){ :existing_method_return_value }
|
15
|
+
|
16
|
+
context "invocation order" do
|
17
|
+
context "#stub" do
|
18
|
+
it "raises an error if 'stub' follows 'with'" do
|
19
|
+
lambda{ klass.any_instance.with("1").stub(:foo) }.should raise_error(NoMethodError)
|
20
|
+
end
|
21
|
+
|
22
|
+
it "raises an error if 'with' follows 'and_return'" do
|
23
|
+
lambda{ klass.any_instance.stub(:foo).and_return(1).with("1") }.should raise_error(NoMethodError)
|
24
|
+
end
|
25
|
+
|
26
|
+
it "raises an error if 'with' follows 'and_raise'" do
|
27
|
+
lambda{ klass.any_instance.stub(:foo).and_raise(1).with("1") }.should raise_error(NoMethodError)
|
28
|
+
end
|
29
|
+
|
30
|
+
it "raises an error if 'with' follows 'and_yield'" do
|
31
|
+
lambda{ klass.any_instance.stub(:foo).and_yield(1).with("1") }.should raise_error(NoMethodError)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context "#should_receive" do
|
36
|
+
it "raises an error if 'should_receive' follows 'with'" do
|
37
|
+
lambda{ klass.any_instance.with("1").should_receive(:foo) }.should raise_error(NoMethodError)
|
38
|
+
end
|
39
|
+
|
40
|
+
it "raises an error if 'with' follows 'and_return'" do
|
41
|
+
pending "see Github issue #42"
|
42
|
+
lambda{ klass.any_instance.should_receive(:foo).and_return(1).with("1") }.should raise_error(NoMethodError)
|
43
|
+
end
|
44
|
+
|
45
|
+
it "raises an error if 'with' follows 'and_raise'" do
|
46
|
+
pending "see Github issue #42"
|
47
|
+
lambda{ klass.any_instance.should_receive(:foo).and_raise(1).with("1") }.should raise_error(NoMethodError)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
context "with #stub" do
|
53
|
+
it "does not suppress an exception when a method that doesn't exist is invoked" do
|
54
|
+
klass.any_instance.stub(:foo)
|
55
|
+
lambda{ klass.new.bar }.should raise_error(NoMethodError)
|
56
|
+
end
|
57
|
+
|
58
|
+
context "behaves as 'every instance'" do
|
59
|
+
it "stubs every instance in the spec" do
|
60
|
+
klass.any_instance.stub(:foo).and_return(result = Object.new)
|
61
|
+
klass.new.foo.should eq(result)
|
62
|
+
klass.new.foo.should eq(result)
|
63
|
+
end
|
64
|
+
|
65
|
+
it "stubs instance created before any_instance was called" do
|
66
|
+
instance = klass.new
|
67
|
+
klass.any_instance.stub(:foo).and_return(result = Object.new)
|
68
|
+
instance.foo.should eq(result)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
context "with #and_return" do
|
73
|
+
it "stubs a method that doesn't exist" do
|
74
|
+
klass.any_instance.stub(:foo).and_return(1)
|
75
|
+
klass.new.foo.should eq(1)
|
76
|
+
end
|
77
|
+
|
78
|
+
it "stubs a method that exists" do
|
79
|
+
klass.any_instance.stub(:existing_method).and_return(1)
|
80
|
+
klass.new.existing_method.should eq(1)
|
81
|
+
end
|
82
|
+
|
83
|
+
it "returns the same object for calls on different instances" do
|
84
|
+
return_value = Object.new
|
85
|
+
klass.any_instance.stub(:foo).and_return(return_value)
|
86
|
+
klass.new.foo.should be(return_value)
|
87
|
+
klass.new.foo.should be(return_value)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
context "with #and_yield" do
|
92
|
+
it "yields the value specified" do
|
93
|
+
yielded_value = Object.new
|
94
|
+
klass.any_instance.stub(:foo).and_yield(yielded_value)
|
95
|
+
klass.new.foo{|value| value.should be(yielded_value)}
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
context "with #and_raise" do
|
100
|
+
it "stubs a method that doesn't exist" do
|
101
|
+
klass.any_instance.stub(:foo).and_raise(CustomErrorForAnyInstanceSpec)
|
102
|
+
lambda{ klass.new.foo}.should raise_error(CustomErrorForAnyInstanceSpec)
|
103
|
+
end
|
104
|
+
|
105
|
+
it "stubs a method that exists" do
|
106
|
+
klass.any_instance.stub(:existing_method).and_raise(CustomErrorForAnyInstanceSpec)
|
107
|
+
lambda{ klass.new.existing_method}.should raise_error(CustomErrorForAnyInstanceSpec)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
context "with a block" do
|
112
|
+
it "stubs a method" do
|
113
|
+
klass.any_instance.stub(:foo) { 1 }
|
114
|
+
klass.new.foo.should eq(1)
|
115
|
+
end
|
116
|
+
|
117
|
+
it "returns the same computed value for calls on different instances" do
|
118
|
+
klass.any_instance.stub(:foo) { 1 + 2 }
|
119
|
+
klass.new.foo.should eq(klass.new.foo)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
context "core ruby objects" do
|
124
|
+
it "works uniformly across *everything*" do
|
125
|
+
Object.any_instance.stub(:foo).and_return(1)
|
126
|
+
Object.new.foo.should eq(1)
|
127
|
+
end
|
128
|
+
|
129
|
+
it "works with the non-standard constructor []" do
|
130
|
+
Array.any_instance.stub(:foo).and_return(1)
|
131
|
+
[].foo.should eq(1)
|
132
|
+
end
|
133
|
+
|
134
|
+
it "works with the non-standard constructor {}" do
|
135
|
+
Hash.any_instance.stub(:foo).and_return(1)
|
136
|
+
{}.foo.should eq(1)
|
137
|
+
end
|
138
|
+
|
139
|
+
it "works with the non-standard constructor \"\"" do
|
140
|
+
String.any_instance.stub(:foo).and_return(1)
|
141
|
+
"".foo.should eq(1)
|
142
|
+
end
|
143
|
+
|
144
|
+
it "works with the non-standard constructor \'\'" do
|
145
|
+
String.any_instance.stub(:foo).and_return(1)
|
146
|
+
''.foo.should eq(1)
|
147
|
+
end
|
148
|
+
|
149
|
+
it "works with the non-standard constructor module" do
|
150
|
+
Module.any_instance.stub(:foo).and_return(1)
|
151
|
+
module RSpec::SampleRspecTestModule;end
|
152
|
+
RSpec::SampleRspecTestModule.foo.should eq(1)
|
153
|
+
end
|
154
|
+
|
155
|
+
it "works with the non-standard constructor class" do
|
156
|
+
Class.any_instance.stub(:foo).and_return(1)
|
157
|
+
class RSpec::SampleRspecTestClass;end
|
158
|
+
RSpec::SampleRspecTestClass.foo.should eq(1)
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
context "with #should_receive" do
|
164
|
+
let(:foo_expectation_error_message) { 'Exactly one instance should have received the following message(s) but didn\'t: foo' }
|
165
|
+
let(:existing_method_expectation_error_message) { 'Exactly one instance should have received the following message(s) but didn\'t: existing_method' }
|
166
|
+
|
167
|
+
context "with an expectation is set on a method which does not exist" do
|
168
|
+
it "returns the expected value" do
|
169
|
+
klass.any_instance.should_receive(:foo).and_return(1)
|
170
|
+
klass.new.foo(1).should eq(1)
|
171
|
+
end
|
172
|
+
|
173
|
+
it "fails if an instance is created but no invocation occurs" do
|
174
|
+
expect do
|
175
|
+
klass.any_instance.should_receive(:foo)
|
176
|
+
klass.new
|
177
|
+
klass.rspec_verify
|
178
|
+
end.to raise_error(RSpec::Mocks::MockExpectationError, foo_expectation_error_message)
|
179
|
+
end
|
180
|
+
|
181
|
+
it "fails if no instance is created" do
|
182
|
+
expect do
|
183
|
+
klass.any_instance.should_receive(:foo).and_return(1)
|
184
|
+
klass.rspec_verify
|
185
|
+
end.to raise_error(RSpec::Mocks::MockExpectationError, foo_expectation_error_message)
|
186
|
+
end
|
187
|
+
|
188
|
+
it "fails if no instance is created and there are multiple expectations" do
|
189
|
+
expect do
|
190
|
+
klass.any_instance.should_receive(:foo)
|
191
|
+
klass.any_instance.should_receive(:bar)
|
192
|
+
klass.rspec_verify
|
193
|
+
end.to raise_error(RSpec::Mocks::MockExpectationError, 'Exactly one instance should have received the following message(s) but didn\'t: bar, foo')
|
194
|
+
end
|
195
|
+
|
196
|
+
it "allows expectations on instances to take priority" do
|
197
|
+
klass.any_instance.should_receive(:foo)
|
198
|
+
klass.new.foo
|
199
|
+
|
200
|
+
instance = klass.new
|
201
|
+
instance.should_receive(:foo).and_return(result = Object.new)
|
202
|
+
instance.foo.should eq(result)
|
203
|
+
end
|
204
|
+
|
205
|
+
context "behaves as 'exactly one instance'" do
|
206
|
+
it "passes if subsequent invocations do not receive that message" do
|
207
|
+
klass.any_instance.should_receive(:foo)
|
208
|
+
klass.new.foo
|
209
|
+
klass.new
|
210
|
+
end
|
211
|
+
|
212
|
+
it "fails if the method is invoked on a second instance" do
|
213
|
+
instance_one = klass.new
|
214
|
+
instance_two = klass.new
|
215
|
+
expect do
|
216
|
+
klass.any_instance.should_receive(:foo)
|
217
|
+
|
218
|
+
instance_one.foo
|
219
|
+
instance_two.foo
|
220
|
+
end.to raise_error(RSpec::Mocks::MockExpectationError, "The message 'foo' was received by #{instance_two.inspect} but has already been received by #{instance_one.inspect}")
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
context "normal expectations on the class object" do
|
225
|
+
it "fail when unfulfilled" do
|
226
|
+
expect do
|
227
|
+
klass.any_instance.should_receive(:foo)
|
228
|
+
klass.should_receive(:woot)
|
229
|
+
klass.new.foo
|
230
|
+
klass.rspec_verify
|
231
|
+
end.to(raise_error(RSpec::Mocks::MockExpectationError) do |error|
|
232
|
+
error.message.should_not eq(existing_method_expectation_error_message)
|
233
|
+
end)
|
234
|
+
end
|
235
|
+
|
236
|
+
|
237
|
+
it "pass when expectations are met" do
|
238
|
+
klass.any_instance.should_receive(:foo)
|
239
|
+
klass.should_receive(:woot).and_return(result = Object.new)
|
240
|
+
klass.new.foo
|
241
|
+
klass.woot.should eq(result)
|
242
|
+
end
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
context "with an expectation is set on a method that exists" do
|
247
|
+
it "returns the expected value" do
|
248
|
+
klass.any_instance.should_receive(:existing_method).and_return(1)
|
249
|
+
klass.new.existing_method(1).should eq(1)
|
250
|
+
end
|
251
|
+
|
252
|
+
it "fails if an instance is created but no invocation occurs" do
|
253
|
+
expect do
|
254
|
+
klass.any_instance.should_receive(:existing_method)
|
255
|
+
klass.new
|
256
|
+
klass.rspec_verify
|
257
|
+
end.to raise_error(RSpec::Mocks::MockExpectationError, existing_method_expectation_error_message)
|
258
|
+
end
|
259
|
+
|
260
|
+
it "fails if no instance is created" do
|
261
|
+
expect do
|
262
|
+
klass.any_instance.should_receive(:existing_method)
|
263
|
+
klass.rspec_verify
|
264
|
+
end.to raise_error(RSpec::Mocks::MockExpectationError, existing_method_expectation_error_message)
|
265
|
+
end
|
266
|
+
|
267
|
+
it "fails if no instance is created and there are multiple expectations" do
|
268
|
+
expect do
|
269
|
+
klass.any_instance.should_receive(:existing_method)
|
270
|
+
klass.any_instance.should_receive(:another_existing_method)
|
271
|
+
klass.rspec_verify
|
272
|
+
end.to raise_error(RSpec::Mocks::MockExpectationError, 'Exactly one instance should have received the following message(s) but didn\'t: another_existing_method, existing_method')
|
273
|
+
end
|
274
|
+
|
275
|
+
context "after any one instance has received a message" do
|
276
|
+
it "passes if subsequent invocations do not receive that message" do
|
277
|
+
klass.any_instance.should_receive(:existing_method)
|
278
|
+
klass.new.existing_method
|
279
|
+
klass.new
|
280
|
+
end
|
281
|
+
|
282
|
+
it "fails if the method is invoked on a second instance" do
|
283
|
+
instance_one = klass.new
|
284
|
+
instance_two = klass.new
|
285
|
+
expect do
|
286
|
+
klass.any_instance.should_receive(:existing_method)
|
287
|
+
|
288
|
+
instance_one.existing_method
|
289
|
+
instance_two.existing_method
|
290
|
+
end.to raise_error(RSpec::Mocks::MockExpectationError, "The message 'existing_method' was received by #{instance_two.inspect} but has already been received by #{instance_one.inspect}")
|
291
|
+
end
|
292
|
+
end
|
293
|
+
end
|
294
|
+
|
295
|
+
context "message count" do
|
296
|
+
context "the 'once' constraint" do
|
297
|
+
it "passes for one invocation" do
|
298
|
+
klass.any_instance.should_receive(:foo).once
|
299
|
+
klass.new.foo
|
300
|
+
end
|
301
|
+
|
302
|
+
it "fails when no instances are declared" do
|
303
|
+
expect do
|
304
|
+
klass.any_instance.should_receive(:foo).once
|
305
|
+
klass.rspec_verify
|
306
|
+
end.to raise_error(RSpec::Mocks::MockExpectationError, foo_expectation_error_message)
|
307
|
+
end
|
308
|
+
|
309
|
+
it "fails when an instance is declared but there are no invocations" do
|
310
|
+
expect do
|
311
|
+
klass.any_instance.should_receive(:foo).once
|
312
|
+
klass.new
|
313
|
+
klass.rspec_verify
|
314
|
+
end.to raise_error(RSpec::Mocks::MockExpectationError, foo_expectation_error_message)
|
315
|
+
end
|
316
|
+
|
317
|
+
it "fails for more than one invocation" do
|
318
|
+
expect do
|
319
|
+
klass.any_instance.should_receive(:foo).once
|
320
|
+
instance = klass.new
|
321
|
+
2.times { instance.foo }
|
322
|
+
instance.rspec_verify
|
323
|
+
end.to raise_error(RSpec::Mocks::MockExpectationError)
|
324
|
+
end
|
325
|
+
end
|
326
|
+
|
327
|
+
context "the 'twice' constraint" do
|
328
|
+
it "passes for two invocations" do
|
329
|
+
klass.any_instance.should_receive(:foo).twice
|
330
|
+
instance = klass.new
|
331
|
+
2.times { instance.foo }
|
332
|
+
end
|
333
|
+
|
334
|
+
it "fails for more than two invocations" do
|
335
|
+
expect do
|
336
|
+
klass.any_instance.should_receive(:foo).twice
|
337
|
+
instance = klass.new
|
338
|
+
3.times { instance.foo }
|
339
|
+
instance.rspec_verify
|
340
|
+
end.to raise_error(RSpec::Mocks::MockExpectationError)
|
341
|
+
end
|
342
|
+
end
|
343
|
+
|
344
|
+
context "the 'exactly(n)' constraint" do
|
345
|
+
it "passes for n invocations where n = 3" do
|
346
|
+
klass.any_instance.should_receive(:foo).exactly(3).times
|
347
|
+
instance = klass.new
|
348
|
+
3.times { instance.foo }
|
349
|
+
end
|
350
|
+
|
351
|
+
it "fails for n invocations where n < 3" do
|
352
|
+
expect do
|
353
|
+
klass.any_instance.should_receive(:foo).exactly(3).times
|
354
|
+
instance = klass.new
|
355
|
+
2.times { instance.foo }
|
356
|
+
instance.rspec_verify
|
357
|
+
end.to raise_error(RSpec::Mocks::MockExpectationError)
|
358
|
+
end
|
359
|
+
|
360
|
+
it "fails for n invocations where n > 3" do
|
361
|
+
expect do
|
362
|
+
klass.any_instance.should_receive(:foo).exactly(3).times
|
363
|
+
instance = klass.new
|
364
|
+
4.times { instance.foo }
|
365
|
+
instance.rspec_verify
|
366
|
+
end.to raise_error(RSpec::Mocks::MockExpectationError)
|
367
|
+
end
|
368
|
+
end
|
369
|
+
|
370
|
+
context "the 'at_least(n)' constraint" do
|
371
|
+
it "passes for n invocations where n = 3" do
|
372
|
+
klass.any_instance.should_receive(:foo).at_least(3).times
|
373
|
+
instance = klass.new
|
374
|
+
3.times { instance.foo }
|
375
|
+
end
|
376
|
+
|
377
|
+
it "fails for n invocations where n < 3" do
|
378
|
+
expect do
|
379
|
+
klass.any_instance.should_receive(:foo).at_least(3).times
|
380
|
+
instance = klass.new
|
381
|
+
2.times { instance.foo }
|
382
|
+
instance.rspec_verify
|
383
|
+
end.to raise_error(RSpec::Mocks::MockExpectationError)
|
384
|
+
end
|
385
|
+
|
386
|
+
it "passes for n invocations where n > 3" do
|
387
|
+
klass.any_instance.should_receive(:foo).at_least(3).times
|
388
|
+
instance = klass.new
|
389
|
+
4.times { instance.foo }
|
390
|
+
end
|
391
|
+
end
|
392
|
+
|
393
|
+
context "the 'at_most(n)' constraint" do
|
394
|
+
it "passes for n invocations where n = 3" do
|
395
|
+
klass.any_instance.should_receive(:foo).at_most(3).times
|
396
|
+
instance = klass.new
|
397
|
+
3.times { instance.foo }
|
398
|
+
end
|
399
|
+
|
400
|
+
it "passes for n invocations where n < 3" do
|
401
|
+
klass.any_instance.should_receive(:foo).at_most(3).times
|
402
|
+
instance = klass.new
|
403
|
+
2.times { instance.foo }
|
404
|
+
end
|
405
|
+
|
406
|
+
it "fails for n invocations where n > 3" do
|
407
|
+
expect do
|
408
|
+
klass.any_instance.should_receive(:foo).at_most(3).times
|
409
|
+
instance = klass.new
|
410
|
+
4.times { instance.foo }
|
411
|
+
instance.rspec_verify
|
412
|
+
end.to raise_error(RSpec::Mocks::MockExpectationError)
|
413
|
+
end
|
414
|
+
end
|
415
|
+
|
416
|
+
context "the 'never' constraint" do
|
417
|
+
it "passes for 0 invocations" do
|
418
|
+
klass.any_instance.should_receive(:foo).never
|
419
|
+
klass.rspec_verify
|
420
|
+
end
|
421
|
+
|
422
|
+
it "fails on the first invocation" do
|
423
|
+
expect do
|
424
|
+
klass.any_instance.should_receive(:foo).never
|
425
|
+
klass.new.foo
|
426
|
+
end.to raise_error(RSpec::Mocks::MockExpectationError)
|
427
|
+
end
|
428
|
+
|
429
|
+
context "when combined with other expectations" do
|
430
|
+
it "passes when the other expecations are met" do
|
431
|
+
klass.any_instance.should_receive(:foo).never
|
432
|
+
klass.any_instance.should_receive(:existing_method).and_return(5)
|
433
|
+
klass.new.existing_method.should eq(5)
|
434
|
+
end
|
435
|
+
|
436
|
+
it "fails when the other expecations are not met" do
|
437
|
+
expect do
|
438
|
+
klass.any_instance.should_receive(:foo).never
|
439
|
+
klass.any_instance.should_receive(:existing_method).and_return(5)
|
440
|
+
klass.rspec_verify
|
441
|
+
end.to raise_error(RSpec::Mocks::MockExpectationError, existing_method_expectation_error_message)
|
442
|
+
end
|
443
|
+
end
|
444
|
+
end
|
445
|
+
|
446
|
+
context "the 'any_number_of_times' constraint" do
|
447
|
+
it "passes for 0 invocations" do
|
448
|
+
klass.any_instance.should_receive(:foo).any_number_of_times
|
449
|
+
klass.new.rspec_verify
|
450
|
+
end
|
451
|
+
|
452
|
+
it "passes for a non-zero number of invocations" do
|
453
|
+
klass.any_instance.should_receive(:foo).any_number_of_times
|
454
|
+
instance = klass.new
|
455
|
+
instance.foo
|
456
|
+
instance.rspec_verify
|
457
|
+
end
|
458
|
+
|
459
|
+
it "does not interfere with other expectations" do
|
460
|
+
klass.any_instance.should_receive(:foo).any_number_of_times
|
461
|
+
klass.any_instance.should_receive(:existing_method).and_return(5)
|
462
|
+
klass.new.existing_method.should eq(5)
|
463
|
+
end
|
464
|
+
|
465
|
+
context "when combined with other expectations" do
|
466
|
+
it "passes when the other expecations are met" do
|
467
|
+
klass.any_instance.should_receive(:foo).any_number_of_times
|
468
|
+
klass.any_instance.should_receive(:existing_method).and_return(5)
|
469
|
+
klass.new.existing_method.should eq(5)
|
470
|
+
end
|
471
|
+
|
472
|
+
it "fails when the other expecations are not met" do
|
473
|
+
expect do
|
474
|
+
klass.any_instance.should_receive(:foo).any_number_of_times
|
475
|
+
klass.any_instance.should_receive(:existing_method).and_return(5)
|
476
|
+
klass.rspec_verify
|
477
|
+
end.to raise_error(RSpec::Mocks::MockExpectationError, existing_method_expectation_error_message)
|
478
|
+
end
|
479
|
+
end
|
480
|
+
end
|
481
|
+
end
|
482
|
+
end
|
483
|
+
|
484
|
+
context "when resetting post-verification" do
|
485
|
+
let(:space) { RSpec::Mocks::Space.new }
|
486
|
+
|
487
|
+
context "existing method" do
|
488
|
+
before(:each) do
|
489
|
+
space.add(klass)
|
490
|
+
end
|
491
|
+
|
492
|
+
context "with stubbing" do
|
493
|
+
before(:each) do
|
494
|
+
klass.any_instance.stub(:existing_method).and_return(1)
|
495
|
+
klass.method_defined?(:__existing_method_without_any_instance__).should be_true
|
496
|
+
end
|
497
|
+
|
498
|
+
it "restores the class to its original state after each example when no instance is created" do
|
499
|
+
space.verify_all
|
500
|
+
|
501
|
+
klass.method_defined?(:__existing_method_without_any_instance__).should be_false
|
502
|
+
klass.new.existing_method.should eq(existing_method_return_value)
|
503
|
+
end
|
504
|
+
|
505
|
+
it "restores the class to its original state after each example when one instance is created" do
|
506
|
+
klass.new.existing_method
|
507
|
+
|
508
|
+
space.verify_all
|
509
|
+
|
510
|
+
klass.method_defined?(:__existing_method_without_any_instance__).should be_false
|
511
|
+
klass.new.existing_method.should eq(existing_method_return_value)
|
512
|
+
end
|
513
|
+
|
514
|
+
it "restores the class to its original state after each example when more than one instance is created" do
|
515
|
+
klass.new.existing_method
|
516
|
+
klass.new.existing_method
|
517
|
+
|
518
|
+
space.verify_all
|
519
|
+
|
520
|
+
klass.method_defined?(:__existing_method_without_any_instance__).should be_false
|
521
|
+
klass.new.existing_method.should eq(existing_method_return_value)
|
522
|
+
end
|
523
|
+
end
|
524
|
+
|
525
|
+
context "with expectations" do
|
526
|
+
context "ensures that the subsequent specs do not see expectations set in previous specs" do
|
527
|
+
context "when the instance created after the expectation is set" do
|
528
|
+
it "first spec" do
|
529
|
+
klass.any_instance.should_receive(:existing_method).and_return(Object.new)
|
530
|
+
klass.new.existing_method
|
531
|
+
end
|
532
|
+
|
533
|
+
it "second spec" do
|
534
|
+
klass.new.existing_method.should eq(existing_method_return_value)
|
535
|
+
end
|
536
|
+
end
|
537
|
+
|
538
|
+
context "when the instance created before the expectation is set" do
|
539
|
+
before :each do
|
540
|
+
@instance = klass.new
|
541
|
+
end
|
542
|
+
|
543
|
+
it "first spec" do
|
544
|
+
klass.any_instance.should_receive(:existing_method).and_return(Object.new)
|
545
|
+
@instance.existing_method
|
546
|
+
end
|
547
|
+
|
548
|
+
it "second spec" do
|
549
|
+
@instance.existing_method.should eq(existing_method_return_value)
|
550
|
+
end
|
551
|
+
end
|
552
|
+
end
|
553
|
+
|
554
|
+
it "ensures that the next spec does not see that expectation" do
|
555
|
+
klass.any_instance.should_receive(:existing_method).and_return(Object.new)
|
556
|
+
klass.new.existing_method
|
557
|
+
space.verify_all
|
558
|
+
|
559
|
+
klass.new.existing_method.should eq(existing_method_return_value)
|
560
|
+
end
|
561
|
+
end
|
562
|
+
end
|
563
|
+
|
564
|
+
it "adds an class to the current space when #any_instance is invoked" do
|
565
|
+
klass.any_instance
|
566
|
+
RSpec::Mocks::space.send(:mocks).should include(klass)
|
567
|
+
end
|
568
|
+
|
569
|
+
it "adds an instance to the current space when stubbed method is invoked" do
|
570
|
+
klass.any_instance.stub(:foo)
|
571
|
+
instance = klass.new
|
572
|
+
instance.foo
|
573
|
+
RSpec::Mocks::space.send(:mocks).should include(instance)
|
574
|
+
end
|
575
|
+
end
|
576
|
+
end
|
577
|
+
end
|
578
|
+
end
|