changelog shortlog tags changeset manifest revisions annotate raw

vendor/plugins/rspec/spec/spec/mocks/mock_spec.rb

changeset 15: 64acf98d15f4
author: moriq@moriq.com
date: Mon Mar 10 10:12:58 2008 +0900 (16 years ago)
permissions: -rw-r--r--
description: add plugins rspec
1require File.dirname(__FILE__) + '/../../spec_helper'
2
3module Spec
4 module Mocks
5 describe Mock do
6
7 before(:each) do
8 @mock = mock("test mock")
9 end
10
11 after(:each) do
12 @mock.rspec_reset
13 end
14
15 it "should report line number of expectation of unreceived message" do
16 expected_error_line = __LINE__; @mock.should_receive(:wont_happen).with("x", 3)
17 begin
18 @mock.rspec_verify
19 violated
20 rescue MockExpectationError => e
21 # NOTE - this regexp ended w/ $, but jruby adds extra info at the end of the line
22 e.backtrace[0].should match(/#{File.basename(__FILE__)}:#{expected_error_line}/)
23 end
24 end
25
26 it "should pass when not receiving message specified as not to be received" do
27 @mock.should_not_receive(:not_expected)
28 @mock.rspec_verify
29 end
30
31 it "should pass when receiving message specified as not to be received with different args" do
32 @mock.should_not_receive(:message).with("unwanted text")
33 @mock.should_receive(:message).with("other text")
34 @mock.message "other text"
35 @mock.rspec_verify
36 end
37
38 it "should fail when receiving message specified as not to be received" do
39 @mock.should_not_receive(:not_expected)
40 @mock.not_expected
41 lambda {
42 @mock.rspec_verify
43 violated
44 }.should raise_error(MockExpectationError, "Mock 'test mock' expected :not_expected with (any args) 0 times, but received it once")
45 end
46
47 it "should fail when receiving message specified as not to be received with args" do
48 @mock.should_not_receive(:not_expected).with("unexpected text")
49 @mock.not_expected("unexpected text")
50 lambda {
51 @mock.rspec_verify
52 violated
53 }.should raise_error(MockExpectationError, "Mock 'test mock' expected :not_expected with (\"unexpected text\") 0 times, but received it once")
54 end
55
56 it "should pass when receiving message specified as not to be received with wrong args" do
57 @mock.should_not_receive(:not_expected).with("unexpected text")
58 @mock.not_expected "really unexpected text"
59 @mock.rspec_verify
60 end
61
62 it "should allow block to calculate return values" do
63 @mock.should_receive(:something).with("a","b","c").and_return { |a,b,c| c+b+a }
64 @mock.something("a","b","c").should == "cba"
65 @mock.rspec_verify
66 end
67
68 it "should allow parameter as return value" do
69 @mock.should_receive(:something).with("a","b","c").and_return("booh")
70 @mock.something("a","b","c").should == "booh"
71 @mock.rspec_verify
72 end
73
74 it "should return nil if no return value set" do
75 @mock.should_receive(:something).with("a","b","c")
76 @mock.something("a","b","c").should be_nil
77 @mock.rspec_verify
78 end
79
80 it "should raise exception if args dont match when method called" do
81 @mock.should_receive(:something).with("a","b","c").and_return("booh")
82 lambda {
83 @mock.something("a","d","c")
84 violated
85 }.should raise_error(MockExpectationError, "Mock 'test mock' expected :something with (\"a\", \"b\", \"c\") but received it with (\"a\", \"d\", \"c\")")
86 end
87
88 it "should fail if unexpected method called" do
89 lambda {
90 @mock.something("a","b","c")
91 violated
92 }.should raise_error(MockExpectationError, "Mock 'test mock' received unexpected message :something with (\"a\", \"b\", \"c\")")
93 end
94
95 it "should use block for expectation if provided" do
96 @mock.should_receive(:something) do | a, b |
97 a.should == "a"
98 b.should == "b"
99 "booh"
100 end
101 @mock.something("a", "b").should == "booh"
102 @mock.rspec_verify
103 end
104
105 it "should fail if expectation block fails" do
106 @mock.should_receive(:something) {| bool | bool.should be_true}
107 lambda {
108 @mock.something false
109 }.should raise_error(MockExpectationError, /Mock 'test mock' received :something but passed block failed with: expected true, got false/)
110 end
111
112 it "should fail right away when method defined as never is received" do
113 pending "Used to pass (false positive). Which one is wrong, the spec or the actual behavior?"
114
115 @mock.should_receive(:not_expected).never
116 lambda {
117 @mock.not_expected
118 }.should raise_error(MockExpectationError, "Mock 'test mock' expected :not_expected 0 times, but received it 1 times")
119 end
120
121 it "should eventually fail when method defined as never is received" do
122 @mock.should_receive(:not_expected).never
123 @mock.not_expected
124
125 lambda {
126 @mock.rspec_verify
127 }.should raise_error(MockExpectationError, "Mock 'test mock' expected :not_expected with (any args) 0 times, but received it once")
128 end
129
130 it "should raise when told to" do
131 @mock.should_receive(:something).and_raise(RuntimeError)
132 lambda do
133 @mock.something
134 end.should raise_error(RuntimeError)
135 end
136
137 it "should raise passed an Exception instance" do
138 error = RuntimeError.new("error message")
139 @mock.should_receive(:something).and_raise(error)
140 lambda {
141 @mock.something
142 }.should raise_error(RuntimeError, "error message")
143 end
144
145 it "should raise RuntimeError with passed message" do
146 @mock.should_receive(:something).and_raise("error message")
147 lambda {
148 @mock.something
149 }.should raise_error(RuntimeError, "error message")
150 end
151
152 it "should not raise when told to if args dont match" do
153 @mock.should_receive(:something).with(2).and_raise(RuntimeError)
154 lambda {
155 @mock.something 1
156 }.should raise_error(MockExpectationError)
157 end
158
159 it "should throw when told to" do
160 @mock.should_receive(:something).and_throw(:blech)
161 lambda {
162 @mock.something
163 }.should throw_symbol(:blech)
164 end
165
166 it "should raise when explicit return and block constrained" do
167 lambda {
168 @mock.should_receive(:fruit) do |colour|
169 :strawberry
170 end.and_return :apple
171 }.should raise_error(AmbiguousReturnError)
172 end
173
174 it "should ignore args on any args" do
175 @mock.should_receive(:something).at_least(:once).with(any_args)
176 @mock.something
177 @mock.something 1
178 @mock.something "a", 2
179 @mock.something [], {}, "joe", 7
180 @mock.rspec_verify
181 end
182
183 it "should fail on no args if any args received" do
184 @mock.should_receive(:something).with(no_args())
185 lambda {
186 @mock.something 1
187 }.should raise_error(MockExpectationError, "Mock 'test mock' expected :something with (no args) but received it with (1)")
188 end
189
190 it "should fail when args are expected but none are received" do
191 @mock.should_receive(:something).with(1)
192 lambda {
193 @mock.something
194 }.should raise_error(MockExpectationError, "Mock 'test mock' expected :something with (1) but received it with (no args)")
195 end
196
197 it "should yield 0 args to blocks that take a variable number of arguments" do
198 @mock.should_receive(:yield_back).with(no_args()).once.and_yield
199 a = nil
200 @mock.yield_back {|*a|}
201 a.should == []
202 @mock.rspec_verify
203 end
204
205 it "should yield 0 args multiple times to blocks that take a variable number of arguments" do
206 @mock.should_receive(:yield_back).once.with(no_args()).once.and_yield.
207 and_yield
208 a = nil
209 b = []
210 @mock.yield_back {|*a| b << a}
211 b.should == [ [], [] ]
212 @mock.rspec_verify
213 end
214
215 it "should yield one arg to blocks that take a variable number of arguments" do
216 @mock.should_receive(:yield_back).with(no_args()).once.and_yield(99)
217 a = nil
218 @mock.yield_back {|*a|}
219 a.should == [99]
220 @mock.rspec_verify
221 end
222
223 it "should yield one arg 3 times consecutively to blocks that take a variable number of arguments" do
224 @mock.should_receive(:yield_back).once.with(no_args()).once.and_yield(99).
225 and_yield(43).
226 and_yield("something fruity")
227 a = nil
228 b = []
229 @mock.yield_back {|*a| b << a}
230 b.should == [[99], [43], ["something fruity"]]
231 @mock.rspec_verify
232 end
233
234 it "should yield many args to blocks that take a variable number of arguments" do
235 @mock.should_receive(:yield_back).with(no_args()).once.and_yield(99, 27, "go")
236 a = nil
237 @mock.yield_back {|*a|}
238 a.should == [99, 27, "go"]
239 @mock.rspec_verify
240 end
241
242 it "should yield many args 3 times consecutively to blocks that take a variable number of arguments" do
243 @mock.should_receive(:yield_back).once.with(no_args()).once.and_yield(99, :green, "go").
244 and_yield("wait", :amber).
245 and_yield("stop", 12, :red)
246 a = nil
247 b = []
248 @mock.yield_back {|*a| b << a}
249 b.should == [[99, :green, "go"], ["wait", :amber], ["stop", 12, :red]]
250 @mock.rspec_verify
251 end
252
253 it "should yield single value" do
254 @mock.should_receive(:yield_back).with(no_args()).once.and_yield(99)
255 a = nil
256 @mock.yield_back {|a|}
257 a.should == 99
258 @mock.rspec_verify
259 end
260
261 it "should yield single value 3 times consecutively" do
262 @mock.should_receive(:yield_back).once.with(no_args()).once.and_yield(99).
263 and_yield(43).
264 and_yield("something fruity")
265 a = nil
266 b = []
267 @mock.yield_back {|a| b << a}
268 b.should == [99, 43, "something fruity"]
269 @mock.rspec_verify
270 end
271
272 it "should yield two values" do
273 @mock.should_receive(:yield_back).with(no_args()).once.and_yield('wha', 'zup')
274 a, b = nil
275 @mock.yield_back {|a,b|}
276 a.should == 'wha'
277 b.should == 'zup'
278 @mock.rspec_verify
279 end
280
281 it "should yield two values 3 times consecutively" do
282 @mock.should_receive(:yield_back).once.with(no_args()).once.and_yield('wha', 'zup').
283 and_yield('not', 'down').
284 and_yield(14, 65)
285 a, b = nil
286 c = []
287 @mock.yield_back {|a,b| c << [a, b]}
288 c.should == [['wha', 'zup'], ['not', 'down'], [14, 65]]
289 @mock.rspec_verify
290 end
291
292 it "should fail when calling yielding method with wrong arity" do
293 @mock.should_receive(:yield_back).with(no_args()).once.and_yield('wha', 'zup')
294 lambda {
295 @mock.yield_back {|a|}
296 }.should raise_error(MockExpectationError, "Mock 'test mock' yielded |\"wha\", \"zup\"| to block with arity of 1")
297 end
298
299 it "should fail when calling yielding method consecutively with wrong arity" do
300 @mock.should_receive(:yield_back).once.with(no_args()).once.and_yield('wha', 'zup').
301 and_yield('down').
302 and_yield(14, 65)
303 lambda {
304 a, b = nil
305 c = []
306 @mock.yield_back {|a,b| c << [a, b]}
307 }.should raise_error(MockExpectationError, "Mock 'test mock' yielded |\"down\"| to block with arity of 2")
308 end
309
310 it "should fail when calling yielding method without block" do
311 @mock.should_receive(:yield_back).with(no_args()).once.and_yield('wha', 'zup')
312 lambda {
313 @mock.yield_back
314 }.should raise_error(MockExpectationError, "Mock 'test mock' asked to yield |[\"wha\", \"zup\"]| but no block was passed")
315 end
316
317 it "should be able to mock send" do
318 @mock.should_receive(:send).with(any_args)
319 @mock.send 'hi'
320 @mock.rspec_verify
321 end
322
323 it "should be able to raise from method calling yielding mock" do
324 @mock.should_receive(:yield_me).and_yield 44
325
326 lambda {
327 @mock.yield_me do |x|
328 raise "Bang"
329 end
330 }.should raise_error(StandardError, "Bang")
331
332 @mock.rspec_verify
333 end
334
335 it "should clear expectations after verify" do
336 @mock.should_receive(:foobar)
337 @mock.foobar
338 @mock.rspec_verify
339 lambda {
340 @mock.foobar
341 }.should raise_error(MockExpectationError, "Mock 'test mock' received unexpected message :foobar with (no args)")
342 end
343
344 it "should restore objects to their original state on rspec_reset" do
345 mock = mock("this is a mock")
346 mock.should_receive(:blah)
347 mock.rspec_reset
348 mock.rspec_verify #should throw if reset didn't work
349 end
350
351 it "should work even after method_missing starts raising NameErrors instead of NoMethodErrors" do
352 # Object#method_missing throws either NameErrors or NoMethodErrors.
353 #
354 # On a fresh ruby program Object#method_missing:
355 # * raises a NoMethodError when called directly
356 # * raises a NameError when called indirectly
357 #
358 # Once Object#method_missing has been called at least once (on any object)
359 # it starts behaving differently:
360 # * raises a NameError when called directly
361 # * raises a NameError when called indirectly
362 #
363 # There was a bug in Mock#method_missing that relied on the fact
364 # that calling Object#method_missing directly raises a NoMethodError.
365 # This example tests that the bug doesn't exist anymore.
366
367
368 # Ensures that method_missing always raises NameErrors.
369 a_method_that_doesnt_exist rescue
370
371
372 @mock.should_receive(:foobar)
373 @mock.foobar
374 @mock.rspec_verify
375
376 lambda { @mock.foobar }.should_not raise_error(NameError)
377 lambda { @mock.foobar }.should raise_error(MockExpectationError)
378 end
379
380 it "should temporarily replace a method stub on a mock" do
381 @mock.stub!(:msg).and_return(:stub_value)
382 @mock.should_receive(:msg).with(:arg).and_return(:mock_value)
383 @mock.msg(:arg).should equal(:mock_value)
384 @mock.msg.should equal(:stub_value)
385 @mock.msg.should equal(:stub_value)
386 @mock.rspec_verify
387 end
388
389 it "should temporarily replace a method stub on a non-mock" do
390 non_mock = Object.new
391 non_mock.stub!(:msg).and_return(:stub_value)
392 non_mock.should_receive(:msg).with(:arg).and_return(:mock_value)
393 non_mock.msg(:arg).should equal(:mock_value)
394 non_mock.msg.should equal(:stub_value)
395 non_mock.msg.should equal(:stub_value)
396 non_mock.rspec_verify
397 end
398
399 it "should assign stub return values" do
400 mock = Mock.new('name', :message => :response)
401 mock.message.should == :response
402 end
403 end
404
405 describe "a mock message receiving a block" do
406 before(:each) do
407 @mock = mock("mock")
408 @calls = 0
409 end
410
411 def add_call
412 @calls = @calls + 1
413 end
414
415 it "should call the block after #should_receive" do
416 @mock.should_receive(:foo) { add_call }
417
418 @mock.foo
419
420 @calls.should == 1
421 end
422
423 it "should call the block after #once" do
424 @mock.should_receive(:foo).once { add_call }
425
426 @mock.foo
427
428 @calls.should == 1
429 end
430
431 it "should call the block after #twice" do
432 @mock.should_receive(:foo).twice { add_call }
433
434 @mock.foo
435 @mock.foo
436
437 @calls.should == 2
438 end
439
440 it "should call the block after #times" do
441 @mock.should_receive(:foo).exactly(10).times { add_call }
442
443 (1..10).each { @mock.foo }
444
445 @calls.should == 10
446 end
447
448 it "should call the block after #any_number_of_times" do
449 @mock.should_receive(:foo).any_number_of_times { add_call }
450
451 (1..7).each { @mock.foo }
452
453 @calls.should == 7
454 end
455
456 it "should call the block after #with" do
457 @mock.should_receive(:foo).with(:arg) { add_call }
458
459 @mock.foo(:arg)
460
461 @calls.should == 1
462 end
463
464 it "should call the block after #ordered" do
465 @mock.should_receive(:foo).ordered { add_call }
466 @mock.should_receive(:bar).ordered { add_call }
467
468 @mock.foo
469 @mock.bar
470
471 @calls.should == 2
472 end
473 end
474 end
475end