1 require File.dirname(__FILE__) + '/../../spec_helper'
8 @mock = mock("test mock")
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)
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}/)
26 it "should pass when not receiving message specified as not to be received" do
27 @mock.should_not_receive(:not_expected)
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"
38 it "should fail when receiving message specified as not to be received" do
39 @mock.should_not_receive(:not_expected)
44 }.should raise_error(MockExpectationError, "Mock 'test mock' expected :not_expected with (any args) 0 times, but received it once")
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")
53 }.should raise_error(MockExpectationError, "Mock 'test mock' expected :not_expected with (\"unexpected text\") 0 times, but received it once")
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"
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"
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"
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
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")
83 @mock.something("a","d","c")
85 }.should raise_error(MockExpectationError, "Mock 'test mock' expected :something with (\"a\", \"b\", \"c\") but received it with (\"a\", \"d\", \"c\")")
88 it "should fail if unexpected method called" do
90 @mock.something("a","b","c")
92 }.should raise_error(MockExpectationError, "Mock 'test mock' received unexpected message :something with (\"a\", \"b\", \"c\")")
95 it "should use block for expectation if provided" do
96 @mock.should_receive(:something) do | a, b |
101 @mock.something("a", "b").should == "booh"
105 it "should fail if expectation block fails" do
106 @mock.should_receive(:something) {| bool | bool.should be_true}
108 @mock.something false
109 }.should raise_error(MockExpectationError, /Mock 'test mock' received :something but passed block failed with: expected true, got false/)
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?"
115 @mock.should_receive(:not_expected).never
118 }.should raise_error(MockExpectationError, "Mock 'test mock' expected :not_expected 0 times, but received it 1 times")
121 it "should eventually fail when method defined as never is received" do
122 @mock.should_receive(:not_expected).never
127 }.should raise_error(MockExpectationError, "Mock 'test mock' expected :not_expected with (any args) 0 times, but received it once")
130 it "should raise when told to" do
131 @mock.should_receive(:something).and_raise(RuntimeError)
134 end.should raise_error(RuntimeError)
137 it "should raise passed an Exception instance" do
138 error = RuntimeError.new("error message")
139 @mock.should_receive(:something).and_raise(error)
142 }.should raise_error(RuntimeError, "error message")
145 it "should raise RuntimeError with passed message" do
146 @mock.should_receive(:something).and_raise("error message")
149 }.should raise_error(RuntimeError, "error message")
152 it "should not raise when told to if args dont match" do
153 @mock.should_receive(:something).with(2).and_raise(RuntimeError)
156 }.should raise_error(MockExpectationError)
159 it "should throw when told to" do
160 @mock.should_receive(:something).and_throw(:blech)
163 }.should throw_symbol(:blech)
166 it "should raise when explicit return and block constrained" do
168 @mock.should_receive(:fruit) do |colour|
170 end.and_return :apple
171 }.should raise_error(AmbiguousReturnError)
174 it "should ignore args on any args" do
175 @mock.should_receive(:something).at_least(:once).with(any_args)
178 @mock.something "a", 2
179 @mock.something [], {}, "joe", 7
183 it "should fail on no args if any args received" do
184 @mock.should_receive(:something).with(no_args())
187 }.should raise_error(MockExpectationError, "Mock 'test mock' expected :something with (no args) but received it with (1)")
190 it "should fail when args are expected but none are received" do
191 @mock.should_receive(:something).with(1)
194 }.should raise_error(MockExpectationError, "Mock 'test mock' expected :something with (1) but received it with (no args)")
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
200 @mock.yield_back {|*a|}
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.
210 @mock.yield_back {|*a| b << a}
211 b.should == [ [], [] ]
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)
218 @mock.yield_back {|*a|}
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).
226 and_yield("something fruity")
229 @mock.yield_back {|*a| b << a}
230 b.should == [[99], [43], ["something fruity"]]
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")
237 @mock.yield_back {|*a|}
238 a.should == [99, 27, "go"]
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)
248 @mock.yield_back {|*a| b << a}
249 b.should == [[99, :green, "go"], ["wait", :amber], ["stop", 12, :red]]
253 it "should yield single value" do
254 @mock.should_receive(:yield_back).with(no_args()).once.and_yield(99)
256 @mock.yield_back {|a|}
261 it "should yield single value 3 times consecutively" do
262 @mock.should_receive(:yield_back).once.with(no_args()).once.and_yield(99).
264 and_yield("something fruity")
267 @mock.yield_back {|a| b << a}
268 b.should == [99, 43, "something fruity"]
272 it "should yield two values" do
273 @mock.should_receive(:yield_back).with(no_args()).once.and_yield('wha', 'zup')
275 @mock.yield_back {|a,b|}
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').
287 @mock.yield_back {|a,b| c << [a, b]}
288 c.should == [['wha', 'zup'], ['not', 'down'], [14, 65]]
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')
295 @mock.yield_back {|a|}
296 }.should raise_error(MockExpectationError, "Mock 'test mock' yielded |\"wha\", \"zup\"| to block with arity of 1")
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').
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")
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')
314 }.should raise_error(MockExpectationError, "Mock 'test mock' asked to yield |[\"wha\", \"zup\"]| but no block was passed")
317 it "should be able to mock send" do
318 @mock.should_receive(:send).with(any_args)
323 it "should be able to raise from method calling yielding mock" do
324 @mock.should_receive(:yield_me).and_yield 44
327 @mock.yield_me do |x|
330 }.should raise_error(StandardError, "Bang")
335 it "should clear expectations after verify" do
336 @mock.should_receive(:foobar)
341 }.should raise_error(MockExpectationError, "Mock 'test mock' received unexpected message :foobar with (no args)")
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)
348 mock.rspec_verify #should throw if reset didn't work
351 it "should work even after method_missing starts raising NameErrors instead of NoMethodErrors" do
352 # Object#method_missing throws either NameErrors or NoMethodErrors.
354 # On a fresh ruby program Object#method_missing:
355 # * raises a NoMethodError when called directly
356 # * raises a NameError when called indirectly
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
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.
368 # Ensures that method_missing always raises NameErrors.
369 a_method_that_doesnt_exist rescue
372 @mock.should_receive(:foobar)
376 lambda { @mock.foobar }.should_not raise_error(NameError)
377 lambda { @mock.foobar }.should raise_error(MockExpectationError)
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)
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
399 it "should assign stub return values" do
400 mock = Mock.new('name', :message => :response)
401 mock.message.should == :response
405 describe "a mock message receiving a block" do
415 it "should call the block after #should_receive" do
416 @mock.should_receive(:foo) { add_call }
423 it "should call the block after #once" do
424 @mock.should_receive(:foo).once { add_call }
431 it "should call the block after #twice" do
432 @mock.should_receive(:foo).twice { add_call }
440 it "should call the block after #times" do
441 @mock.should_receive(:foo).exactly(10).times { add_call }
443 (1..10).each { @mock.foo }
448 it "should call the block after #any_number_of_times" do
449 @mock.should_receive(:foo).any_number_of_times { add_call }
451 (1..7).each { @mock.foo }
456 it "should call the block after #with" do
457 @mock.should_receive(:foo).with(:arg) { add_call }
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 }