1 require File.dirname(__FILE__) + '/../../spec_helper'
5 describe "a Mock expectation" do
8 @mock = mock("test mock")
15 it "should report line number of expectation of unreceived message" do
16 @mock.should_receive(:wont_happen).with("x", 3)
17 #NOTE - this test is quite ticklish because it specifies that
18 #the above statement appears on line 12 of this file.
23 rescue MockExpectationError => e
24 e.backtrace[0].should match(/mock_spec\.rb:16/)
29 it "should pass when not receiving message specified as not to be received" do
30 @mock.should_not_receive(:not_expected)
34 it "should pass when receiving message specified as not to be received with different args" do
35 @mock.should_not_receive(:message).with("unwanted text")
36 @mock.should_receive(:message).with("other text")
37 @mock.message "other text"
41 it "should fail when receiving message specified as not to be received" do
42 @mock.should_not_receive(:not_expected)
47 rescue MockExpectationError => e
48 e.message.should == "Mock 'test mock' expected :not_expected with (any args) 0 times, but received it once"
52 it "should fail when receiving message specified as not to be received with args" do
53 @mock.should_not_receive(:not_expected).with("unexpected text")
54 @mock.not_expected("unexpected text")
58 rescue MockExpectationError => e
59 e.message.should == "Mock 'test mock' expected :not_expected with (\"unexpected text\") 0 times, but received it once"
63 it "should pass when receiving message specified as not to be received with wrong args" do
64 @mock.should_not_receive(:not_expected).with("unexpected text")
65 @mock.not_expected "really unexpected text"
69 it "should allow block to calculate return values" do
70 @mock.should_receive(:something).with("a","b","c").and_return { |a,b,c| c+b+a }
71 @mock.something("a","b","c").should == "cba"
75 it "should allow parameter as return value" do
76 @mock.should_receive(:something).with("a","b","c").and_return("booh")
77 @mock.something("a","b","c").should == "booh"
81 it "should return nil if no return value set" do
82 @mock.should_receive(:something).with("a","b","c")
83 @mock.something("a","b","c").should be_nil
87 it "should raise exception if args dont match when method called" do
88 @mock.should_receive(:something).with("a","b","c").and_return("booh")
90 @mock.something("a","d","c")
92 rescue MockExpectationError => e
93 e.message.should == "Mock 'test mock' expected :something with (\"a\", \"b\", \"c\") but received it with (\"a\", \"d\", \"c\")"
97 it "should fail if unexpected method called" do
99 @mock.something("a","b","c")
101 rescue MockExpectationError => e
102 e.message.should == "Mock 'test mock' received unexpected message :something with (\"a\", \"b\", \"c\")"
106 it "should use block for expectation if provided" do
107 @mock.should_receive(:something) do | a, b |
112 @mock.something("a", "b").should == "booh"
116 it "should fail if expectation block fails" do
117 @mock.should_receive(:something) {| bool | bool.should be_true}
119 @mock.something false
120 rescue MockExpectationError => e
121 e.message.should match(/Mock 'test mock' received :something but passed block failed with: expected true, got false/)
125 it "should fail when method defined as never is received" do
126 @mock.should_receive(:not_expected).never
129 rescue MockExpectationError => e
130 e.message.should == "Mock 'test mock' expected :not_expected 0 times, but received it 1 times"
134 it "should raise when told to" do
135 @mock.should_receive(:something).and_raise(RuntimeError)
138 end.should raise_error(RuntimeError)
141 it "should raise passed an Exception instance" do
142 error = RuntimeError.new("error message")
143 @mock.should_receive(:something).and_raise(error)
146 rescue RuntimeError => e
147 e.message.should eql("error message")
151 it "should raise RuntimeError with passed message" do
152 @mock.should_receive(:something).and_raise("error message")
155 rescue RuntimeError => e
156 e.message.should eql("error message")
160 it "should not raise when told to if args dont match" do
161 @mock.should_receive(:something).with(2).and_raise(RuntimeError)
164 end.should raise_error(MockExpectationError)
167 it "should throw when told to" do
168 @mock.should_receive(:something).and_throw(:blech)
171 end.should throw_symbol(:blech)
174 it "should raise when explicit return and block constrained" do
176 @mock.should_receive(:fruit) do |colour|
178 end.and_return :apple
179 end.should raise_error(AmbiguousReturnError)
182 it "should ignore args on any args" do
183 @mock.should_receive(:something).at_least(:once).with(any_args)
186 @mock.something "a", 2
187 @mock.something [], {}, "joe", 7
191 it "should fail on no args if any args received" do
192 @mock.should_receive(:something).with(no_args())
195 rescue MockExpectationError => e
196 e.message.should == "Mock 'test mock' expected :something with (no args) but received it with (1)"
200 it "should fail when args are expected but none are received" do
201 @mock.should_receive(:something).with(1)
204 rescue MockExpectationError => e
205 e.message.should == "Mock 'test mock' expected :something with (1) but received it with (no args)"
209 it "should yield 0 args to blocks that take a variable number of arguments" do
210 @mock.should_receive(:yield_back).with(no_args()).once.and_yield
212 @mock.yield_back {|*a|}
217 it "should yield one arg to blocks that take a variable number of arguments" do
218 @mock.should_receive(:yield_back).with(no_args()).once.and_yield(99)
220 @mock.yield_back {|*a|}
225 it "should yield many args to blocks that take a variable number of arguments" do
226 @mock.should_receive(:yield_back).with(no_args()).once.and_yield(99, 27, "go")
228 @mock.yield_back {|*a|}
229 a.should == [99, 27, "go"]
233 it "should yield single value" do
234 @mock.should_receive(:yield_back).with(no_args()).once.and_yield(99)
236 @mock.yield_back {|a|}
241 it "should yield two values" do
242 @mock.should_receive(:yield_back).with(no_args()).once.and_yield('wha', 'zup')
244 @mock.yield_back {|a,b|}
250 it "should fail when calling yielding method with wrong arity" do
251 @mock.should_receive(:yield_back).with(no_args()).once.and_yield('wha', 'zup')
253 @mock.yield_back {|a|}
254 rescue MockExpectationError => e
255 e.message.should == "Mock 'test mock' yielded |\"wha\", \"zup\"| to block with arity of 1"
259 it "should fail when calling yielding method without block" do
260 @mock.should_receive(:yield_back).with(no_args()).once.and_yield('wha', 'zup')
263 rescue MockExpectationError => e
264 e.message.should == "Mock 'test mock' asked to yield |\"wha\", \"zup\"| but no block was passed"
268 it "should be able to mock send" do
269 @mock.should_receive(:send).with(any_args)
274 it "should be able to raise from method calling yielding mock" do
275 @mock.should_receive(:yield_me).and_yield 44
278 @mock.yield_me do |x|
281 end.should raise_error(StandardError)
286 # TODO - this is failing, but not if you run the file w/ --reverse - weird!!!!!!
287 # specify "should clear expectations after verify" do
288 # @mock.should_receive(:foobar)
293 # rescue MockExpectationError => e
294 # e.message.should == "Mock 'test mock' received unexpected message :foobar with (no args)"
298 it "should restore objects to their original state on rspec_reset" do
299 mock = mock("this is a mock")
300 mock.should_receive(:blah)
302 mock.rspec_verify #should throw if reset didn't work
307 describe "a mock message receiving a block" do
317 it "should call the block after #should_receive" do
318 @mock.should_receive(:foo) { add_call }
325 it "should call the block after #once" do
326 @mock.should_receive(:foo).once { add_call }
333 it "should call the block after #twice" do
334 @mock.should_receive(:foo).twice { add_call }
342 it "should call the block after #times" do
343 @mock.should_receive(:foo).exactly(10).times { add_call }
345 (1..10).each { @mock.foo }
350 it "should call the block after #any_number_of_times" do
351 @mock.should_receive(:foo).any_number_of_times { add_call }
353 (1..7).each { @mock.foo }
358 it "should call the block after #with" do
359 @mock.should_receive(:foo).with(:arg) { add_call }
366 it "should call the block after #ordered" do
367 @mock.should_receive(:foo).ordered { add_call }
368 @mock.should_receive(:bar).ordered { add_call }