Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 431 lines (327 sloc) 15.719 kb
cceb0e8 @JonRowe Badges are crisper as svg
JonRowe authored
1 # RSpec Mocks [![Build Status](https://secure.travis-ci.org/rspec/rspec-mocks.svg?branch=master)](http://travis-ci.org/rspec/rspec-mocks) [![Code Climate](https://codeclimate.com/github/rspec/rspec-mocks.svg)](https://codeclimate.com/github/rspec/rspec-mocks)
f4bd883 @dchelimsky rdoc (and a rename or two)
dchelimsky authored
2 rspec-mocks is a test-double framework for rspec with support for method stubs,
3 fakes, and message expectations on generated test-doubles and real objects
4 alike.
f9f8418 @dchelimsky words
dchelimsky authored
5
6084658 @dchelimsky links to docs
dchelimsky authored
6 ## Install
f9f8418 @dchelimsky words
dchelimsky authored
7
6084658 @dchelimsky links to docs
dchelimsky authored
8 gem install rspec # for rspec-core, rspec-expectations, rspec-mocks
9 gem install rspec-mocks # for rspec-mocks only
d5a1da7 @spicycode Initial jeweler repository creation
spicycode authored
10
d65446b @cupakromer Include details on how to run against `master`.
cupakromer authored
11 Want to run against the `master` branch? You'll need to include the dependent
12 RSpec repos as well. Add the following to your `Gemfile`:
13
14 ```ruby
15 %w[rspec-core rspec-expectations rspec-mocks rspec-support].each do |lib|
16 gem lib, :git => "git://github.com/rspec/#{lib}.git", :branch => 'master'
17 end
18 ```
19
c186d12 @dchelimsky move overview to Readme (where it belongs)
dchelimsky authored
20 ## Test Doubles
21
c7ac609 @xaviershay Consistent double documentation across README and features README.
xaviershay authored
22 A test double is an object that stands in for another object in your system
b01f908 @stuarthicks Update Readme to mention what the parameter is for double() and that it ...
stuarthicks authored
23 during a code example. Use the `double` method, passing in an optional identifier, to create one:
c186d12 @dchelimsky move overview to Readme (where it belongs)
dchelimsky authored
24
a13dd64 @icambron added ruby syntax highlighting for github
icambron authored
25 ```ruby
4cae12c @xaviershay Fix accidental reference to account.
xaviershay authored
26 book = double("book")
a13dd64 @icambron added ruby syntax highlighting for github
icambron authored
27 ```
c186d12 @dchelimsky move overview to Readme (where it belongs)
dchelimsky authored
28
32d85e9 @xaviershay Add verifying doubles to README.
xaviershay authored
29 Most of the time you will want some confidence that your doubles resemble an
30 existing object in your system. Verifying doubles are provided for this
31 purpose. If the existing object is available, they will prevent you from adding
32 stubs and expectations for methods that do not exist or that have an invalid
33 number of parameters.
34
35 ```ruby
36 book = instance_double("Book", :pages => 250)
37 ```
38
39 Verifying doubles have some clever tricks to enable you to both test in
40 isolation without your dependencies loaded while still being able to validate
d81cfc0 @wicz Fix Markdown link
wicz authored
41 them against real objects. More detail is available in [their
42 documentation](https://github.com/rspec/rspec-mocks/blob/master/features/verifying_doubles).
32d85e9 @xaviershay Add verifying doubles to README.
xaviershay authored
43
b5985e7 @e2 mention naming verifying doubles in README
e2 authored
44 Verifying doubles can also accept custom identifiers, just like double(), e.g.:
45
46 ```ruby
47 books = []
48 books << instance_double("Book", :rspec_book, :pages => 250)
49 books << instance_double("Book", "(Untitled)", :pages => 5000)
50
51 puts books.inspect # with names, it's clearer which were actually added
52 ```
53
f26af00 @dchelimsky words
dchelimsky authored
54 ## Method Stubs
55
0a824d2 @dchelimsky more README
dchelimsky authored
56 A method stub is an implementation that returns a pre-determined value. Method
57 stubs can be declared on test doubles or real objects using the same syntax.
58 rspec-mocks supports 3 forms for declaring method stubs:
c186d12 @dchelimsky move overview to Readme (where it belongs)
dchelimsky authored
59
a13dd64 @icambron added ruby syntax highlighting for github
icambron authored
60 ```ruby
1f370af @thomas-holmes Update README.md to use expect syntax.
thomas-holmes authored
61 allow(book).to receive(:title) { "The RSpec Book" }
62 allow(book).to receive(:title).and_return("The RSpec Book")
5e6d687 @piotrj Add receive_messages to README
piotrj authored
63 allow(book).to receive_messages(
f8c1fd8 @imtayadeway Fix typo on README line 380.
imtayadeway authored
64 :title => "The RSpec Book",
5e6d687 @piotrj Add receive_messages to README
piotrj authored
65 :subtitle => "Behaviour-Driven Development with RSpec, Cucumber, and Friends")
a13dd64 @icambron added ruby syntax highlighting for github
icambron authored
66 ```
c186d12 @dchelimsky move overview to Readme (where it belongs)
dchelimsky authored
67
0a824d2 @dchelimsky more README
dchelimsky authored
68 You can also use this shortcut, which creates a test double and declares a
69 method stub in one statement:
c186d12 @dchelimsky move overview to Readme (where it belongs)
dchelimsky authored
70
a13dd64 @icambron added ruby syntax highlighting for github
icambron authored
71 ```ruby
f86db3e @icambron removed extra indentation in readme
icambron authored
72 book = double("book", :title => "The RSpec Book")
a13dd64 @icambron added ruby syntax highlighting for github
icambron authored
73 ```
c186d12 @dchelimsky move overview to Readme (where it belongs)
dchelimsky authored
74
609e365 @behrends Fix typo
behrends authored
75 The first argument is a name, which is used for documentation and appears in
0a824d2 @dchelimsky more README
dchelimsky authored
76 failure messages. If you don't care about the name, you can leave it out,
77 making the combined instantiation/stub declaration very terse:
c186d12 @dchelimsky move overview to Readme (where it belongs)
dchelimsky authored
78
a13dd64 @icambron added ruby syntax highlighting for github
icambron authored
79 ```ruby
f86db3e @icambron removed extra indentation in readme
icambron authored
80 double(:foo => 'bar')
a13dd64 @icambron added ruby syntax highlighting for github
icambron authored
81 ```
f26af00 @dchelimsky words
dchelimsky authored
82
0a824d2 @dchelimsky more README
dchelimsky authored
83 This is particularly nice when providing a list of test doubles to a method
84 that iterates through them:
85
a13dd64 @icambron added ruby syntax highlighting for github
icambron authored
86 ```ruby
86abf8d @myronmarston Fixup README code formatting.
myronmarston authored
87 order.calculate_total_price(double(:price => 1.99), double(:price => 2.99))
a13dd64 @icambron added ruby syntax highlighting for github
icambron authored
88 ```
0a824d2 @dchelimsky more README
dchelimsky authored
89
90 ## Consecutive return values
91
92 When a stub might be invoked more than once, you can provide additional
93 arguments to `and_return`. The invocations cycle through the list. The last
94 value is returned for any subsequent invocations:
95
a13dd64 @icambron added ruby syntax highlighting for github
icambron authored
96 ```ruby
86abf8d @myronmarston Fixup README code formatting.
myronmarston authored
97 allow(die).to receive(:roll).and_return(1, 2, 3)
f86db3e @icambron removed extra indentation in readme
icambron authored
98 die.roll # => 1
99 die.roll # => 2
100 die.roll # => 3
101 die.roll # => 3
102 die.roll # => 3
a13dd64 @icambron added ruby syntax highlighting for github
icambron authored
103 ```
0a824d2 @dchelimsky more README
dchelimsky authored
104
105 To return an array in a single invocation, declare an array:
106
a13dd64 @icambron added ruby syntax highlighting for github
icambron authored
107 ```ruby
4993498 @thomas-holmes Put hashrockets back in place
thomas-holmes authored
108 allow(team).to receive(:players).and_return([double(:name => "David")])
a13dd64 @icambron added ruby syntax highlighting for github
icambron authored
109 ```
0a824d2 @dchelimsky more README
dchelimsky authored
110
f26af00 @dchelimsky words
dchelimsky authored
111 ## Message Expectations
112
c186d12 @dchelimsky move overview to Readme (where it belongs)
dchelimsky authored
113 A message expectation is an expectation that the test double will receive a
114 message some time before the example ends. If the message is received, the
115 expectation is satisfied. If not, the example fails.
116
a13dd64 @icambron added ruby syntax highlighting for github
icambron authored
117 ```ruby
f86db3e @icambron removed extra indentation in readme
icambron authored
118 validator = double("validator")
1f370af @thomas-holmes Update README.md to use expect syntax.
thomas-holmes authored
119 expect(validator).to receive(:validate) { "02134" }
f86db3e @icambron removed extra indentation in readme
icambron authored
120 zipcode = Zipcode.new("02134", validator)
121 zipcode.valid?
a13dd64 @icambron added ruby syntax highlighting for github
icambron authored
122 ```
c186d12 @dchelimsky move overview to Readme (where it belongs)
dchelimsky authored
123
5e19fe9 Add documentation for Spies in README
Adarsh Pandit authored
124 ## Test Spies
125
0fd2266 @samphippen Adds spying methods to the RSpec Mocks DSL
samphippen authored
126 Verifies the given object received the expected message during the course of
127 the test. For a message to be verified, the given object must be setup to spy
128 on it, either by having it explicitly stubbed or by being a null object double
129 (e.g. `double(...).as_null_object`). Convenience methods are provided to easily
130 create null object doubles for this purpose:
131
132 ```ruby
e21dc8b @omartell Fix invitation typo in readme
omartell authored
133 spy("invitation") # => same as `double("invitation").as_null_object`
134 instance_spy("Invitation") # => same as `instance_double("Invitation").as_null_object`
135 class_spy("Invitation") # => same as `class_double("Invitation").as_null_object`
136 object_spy("Invitation") # => same as `object_double("Invitation").as_null_object`
0fd2266 @samphippen Adds spying methods to the RSpec Mocks DSL
samphippen authored
137 ```
5e19fe9 Add documentation for Spies in README
Adarsh Pandit authored
138
8d071d5 @myronmarston Stop calling methods on args passed to a stubbed method.
myronmarston authored
139 Verifying messages received in this way implements the Test Spy pattern.
5e19fe9 Add documentation for Spies in README
Adarsh Pandit authored
140
141 ```ruby
8ba17ed @igas Fix indentation in readme
igas authored
142 invitation = spy('invitation')
5e19fe9 Add documentation for Spies in README
Adarsh Pandit authored
143
8ba17ed @igas Fix indentation in readme
igas authored
144 user.accept_invitation(invitation)
5e19fe9 Add documentation for Spies in README
Adarsh Pandit authored
145
8ba17ed @igas Fix indentation in readme
igas authored
146 expect(invitation).to have_received(:accept)
5e19fe9 Add documentation for Spies in README
Adarsh Pandit authored
147
8ba17ed @igas Fix indentation in readme
igas authored
148 # You can also use other common message expectations. For example:
149 expect(invitation).to have_received(:accept).with(mailer)
150 expect(invitation).to have_received(:accept).twice
151 expect(invitation).to_not have_received(:accept).with(mailer)
0fd2266 @samphippen Adds spying methods to the RSpec Mocks DSL
samphippen authored
152
8ba17ed @igas Fix indentation in readme
igas authored
153 # One can specify a return value on the spy the same way one would a double.
154 invitation = spy('invitation', :accept => true)
155 expect(invitation).to have_received(:accept).with(mailer)
156 expect(invitation.accept).to eq(true)
5e19fe9 Add documentation for Spies in README
Adarsh Pandit authored
157 ```
158
8d071d5 @myronmarston Stop calling methods on args passed to a stubbed method.
myronmarston authored
159 Note that `have_received(...).with(...)` is unable to work properly when
160 passed arguments are mutated after the spy records the received message.
161 For example, this does not work properly:
162
163 ```ruby
164 greeter = spy("greeter")
165
166 message = "Hello"
167 greeter.greet_with(message)
168 message << ", World"
169
170 expect(greeter).to have_received(:greet_with).with("Hello")
171 ```
172
c186d12 @dchelimsky move overview to Readme (where it belongs)
dchelimsky authored
173 ## Nomenclature
174
175 ### Mock Objects and Test Stubs
176
177 The names Mock Object and Test Stub suggest specialized Test Doubles. i.e.
178 a Test Stub is a Test Double that only supports method stubs, and a Mock
179 Object is a Test Double that supports message expectations and method
180 stubs.
181
182 There is a lot of overlapping nomenclature here, and there are many
183 variations of these patterns (fakes, spies, etc). Keep in mind that most of
184 the time we're talking about method-level concepts that are variations of
185 method stubs and message expectations, and we're applying to them to _one_
186 generic kind of object: a Test Double.
187
188 ### Test-Specific Extension
189
ef4aa3b @myronmarston Rename `Mock` to `Double` in class names, etc.
myronmarston authored
190 a.k.a. Partial Double, a Test-Specific Extension is an extension of a
c186d12 @dchelimsky move overview to Readme (where it belongs)
dchelimsky authored
191 real object in a system that is instrumented with test-double like
192 behaviour in the context of a test. This technique is very common in Ruby
193 because we often see class objects acting as global namespaces for methods.
194 For example, in Rails:
195
a13dd64 @icambron added ruby syntax highlighting for github
icambron authored
196 ```ruby
f86db3e @icambron removed extra indentation in readme
icambron authored
197 person = double("person")
1f370af @thomas-holmes Update README.md to use expect syntax.
thomas-holmes authored
198 allow(Person).to receive(:find) { person }
a13dd64 @icambron added ruby syntax highlighting for github
icambron authored
199 ```
c186d12 @dchelimsky move overview to Readme (where it belongs)
dchelimsky authored
200
201 In this case we're instrumenting Person to return the person object we've
155cef3 @dchelimsky Make the fact that you can set message expectations on class objects
dchelimsky authored
202 defined whenever it receives the `find` message. We can also set a message
203 expectation so that the example fails if `find` is not called:
204
205 ```ruby
206 person = double("person")
1f370af @thomas-holmes Update README.md to use expect syntax.
thomas-holmes authored
207 expect(Person).to receive(:find) { person }
155cef3 @dchelimsky Make the fact that you can set message expectations on class objects
dchelimsky authored
208 ```
209
68a4a1c @granth remove reference to stub and should_receive from README
granth authored
210 RSpec replaces the method we're stubbing or mocking with its own
155cef3 @dchelimsky Make the fact that you can set message expectations on class objects
dchelimsky authored
211 test-double-like method. At the end of the example, RSpec verifies any message
212 expectations, and then restores the original methods.
c186d12 @dchelimsky move overview to Readme (where it belongs)
dchelimsky authored
213
214 ## Expecting Arguments
215
a13dd64 @icambron added ruby syntax highlighting for github
icambron authored
216 ```ruby
1f370af @thomas-holmes Update README.md to use expect syntax.
thomas-holmes authored
217 expect(double).to receive(:msg).with(*args)
218 expect(double).to_not receive(:msg).with(*args)
a13dd64 @icambron added ruby syntax highlighting for github
icambron authored
219 ```
c186d12 @dchelimsky move overview to Readme (where it belongs)
dchelimsky authored
220
d0df33c @dchelimsky fix type in README (that I introduced in previous commit)
dchelimsky authored
221 You can set multiple expectations for the same message if you need to:
eea518f @dchelimsky add note about expecting same message multiple times with diff args to R...
dchelimsky authored
222
223 ```ruby
1f370af @thomas-holmes Update README.md to use expect syntax.
thomas-holmes authored
224 expect(double).to receive(:msg).with("A", 1, 3)
225 expect(double).to receive(:msg).with("B", 2, 4)
eea518f @dchelimsky add note about expecting same message multiple times with diff args to R...
dchelimsky authored
226 ```
227
c186d12 @dchelimsky move overview to Readme (where it belongs)
dchelimsky authored
228 ## Argument Matchers
229
f4bd883 @dchelimsky rdoc (and a rename or two)
dchelimsky authored
230 Arguments that are passed to `with` are compared with actual arguments
c186d12 @dchelimsky move overview to Readme (where it belongs)
dchelimsky authored
231 received using ==. In cases in which you want to specify things about the
232 arguments rather than the arguments themselves, you can use any of the
233 matchers that ship with rspec-expectations. They don't all make syntactic
234 sense (they were primarily designed for use with RSpec::Expectations), but
235 you are free to create your own custom RSpec::Matchers.
236
237 rspec-mocks also adds some keyword Symbols that you can use to
238 specify certain kinds of arguments:
239
a13dd64 @icambron added ruby syntax highlighting for github
icambron authored
240 ```ruby
c3c94fa @myronmarston Update `any_args` docs to explain splat semantics.
myronmarston authored
241 expect(double).to receive(:msg).with(no_args)
242 expect(double).to receive(:msg).with(any_args)
243 expect(double).to receive(:msg).with(1, any_args) # any args acts like an arg splat and can go anywhere
1f370af @thomas-holmes Update README.md to use expect syntax.
thomas-holmes authored
244 expect(double).to receive(:msg).with(1, kind_of(Numeric), "b") #2nd argument can be any kind of Numeric
245 expect(double).to receive(:msg).with(1, boolean(), "b") #2nd argument can be true or false
246 expect(double).to receive(:msg).with(1, /abc/, "b") #2nd argument can be any String matching the submitted Regexp
247 expect(double).to receive(:msg).with(1, anything(), "b") #2nd argument can be anything at all
654b34a @JonRowe cleanup readme post #742
JonRowe authored
248 expect(double).to receive(:msg).with(1, duck_type(:abs, :div), "b") #2nd argument can be object that responds to #abs and #div
249 expect(double).to receive(:msg).with(hash_including(:a => 5)) # first arg is a hash with a: 5 as one of the key-values
c2aa35c @ktaragorn Add undocumented argument matchers to README
ktaragorn authored
250 expect(double).to receive(:msg).with(array_including(5)) # first arg is an array with 5 as one of the key-values
654b34a @JonRowe cleanup readme post #742
JonRowe authored
251 expect(double).to receive(:msg).with(hash_excluding(:a => 5)) # first arg is a hash without a: 5 as one of the key-values
a13dd64 @icambron added ruby syntax highlighting for github
icambron authored
252 ```
c186d12 @dchelimsky move overview to Readme (where it belongs)
dchelimsky authored
253
254 ## Receive Counts
255
a13dd64 @icambron added ruby syntax highlighting for github
icambron authored
256 ```ruby
1f370af @thomas-holmes Update README.md to use expect syntax.
thomas-holmes authored
257 expect(double).to receive(:msg).once
258 expect(double).to receive(:msg).twice
259 expect(double).to receive(:msg).exactly(n).times
260 expect(double).to receive(:msg).at_least(:once)
261 expect(double).to receive(:msg).at_least(:twice)
262 expect(double).to receive(:msg).at_least(n).times
263 expect(double).to receive(:msg).at_most(:once)
264 expect(double).to receive(:msg).at_most(:twice)
265 expect(double).to receive(:msg).at_most(n).times
a13dd64 @icambron added ruby syntax highlighting for github
icambron authored
266 ```
c186d12 @dchelimsky move overview to Readme (where it belongs)
dchelimsky authored
267
268 ## Ordering
269
a13dd64 @icambron added ruby syntax highlighting for github
icambron authored
270 ```ruby
1f370af @thomas-holmes Update README.md to use expect syntax.
thomas-holmes authored
271 expect(double).to receive(:msg).ordered
272 expect(double).to receive(:other_msg).ordered
86abf8d @myronmarston Fixup README code formatting.
myronmarston authored
273 # This will fail if the messages are received out of order
a13dd64 @icambron added ruby syntax highlighting for github
icambron authored
274 ```
c186d12 @dchelimsky move overview to Readme (where it belongs)
dchelimsky authored
275
42faffa @dchelimsky more about should_receive multiple times with args in README
dchelimsky authored
276 This can include the same message with different arguments:
277
278 ```ruby
1f370af @thomas-holmes Update README.md to use expect syntax.
thomas-holmes authored
279 expect(double).to receive(:msg).with("A", 1, 3).ordered
280 expect(double).to receive(:msg).with("B", 2, 4).ordered
42faffa @dchelimsky more about should_receive multiple times with args in README
dchelimsky authored
281 ```
282
40a2a0f @CoryFoy Correct spelling of "Responses"
CoryFoy authored
283 ## Setting Responses
c186d12 @dchelimsky move overview to Readme (where it belongs)
dchelimsky authored
284
285 Whether you are setting a message expectation or a method stub, you can
286 tell the object precisely how to respond. The most generic way is to pass
1f370af @thomas-holmes Update README.md to use expect syntax.
thomas-holmes authored
287 a block to `receive`:
c186d12 @dchelimsky move overview to Readme (where it belongs)
dchelimsky authored
288
a13dd64 @icambron added ruby syntax highlighting for github
icambron authored
289 ```ruby
1f370af @thomas-holmes Update README.md to use expect syntax.
thomas-holmes authored
290 expect(double).to receive(:msg) { value }
a13dd64 @icambron added ruby syntax highlighting for github
icambron authored
291 ```
c186d12 @dchelimsky move overview to Readme (where it belongs)
dchelimsky authored
292
f4bd883 @dchelimsky rdoc (and a rename or two)
dchelimsky authored
293 When the double receives the `msg` message, it evaluates the block and returns
c186d12 @dchelimsky move overview to Readme (where it belongs)
dchelimsky authored
294 the result.
295
a13dd64 @icambron added ruby syntax highlighting for github
icambron authored
296 ```ruby
1f370af @thomas-holmes Update README.md to use expect syntax.
thomas-holmes authored
297 expect(double).to receive(:msg).and_return(value)
298 expect(double).to receive(:msg).exactly(3).times.and_return(value1, value2, value3)
f86db3e @icambron removed extra indentation in readme
icambron authored
299 # returns value1 the first time, value2 the second, etc
1f370af @thomas-holmes Update README.md to use expect syntax.
thomas-holmes authored
300 expect(double).to receive(:msg).and_raise(error)
86abf8d @myronmarston Fixup README code formatting.
myronmarston authored
301 # error can be an instantiated object or a class
302 # if it is a class, it must be instantiable with no args
1f370af @thomas-holmes Update README.md to use expect syntax.
thomas-holmes authored
303 expect(double).to receive(:msg).and_throw(:msg)
86abf8d @myronmarston Fixup README code formatting.
myronmarston authored
304 expect(double).to receive(:msg).and_yield(values, to, yield)
305 expect(double).to receive(:msg).and_yield(values, to, yield).and_yield(some, other, values, this, time)
f86db3e @icambron removed extra indentation in readme
icambron authored
306 # for methods that yield to a block multiple times
a13dd64 @icambron added ruby syntax highlighting for github
icambron authored
307 ```
c186d12 @dchelimsky move overview to Readme (where it belongs)
dchelimsky authored
308
309 Any of these responses can be applied to a stub as well
310
a13dd64 @icambron added ruby syntax highlighting for github
icambron authored
311 ```ruby
1f370af @thomas-holmes Update README.md to use expect syntax.
thomas-holmes authored
312 allow(double).to receive(:msg).and_return(value)
313 allow(double).to receive(:msg).and_return(value1, value2, value3)
314 allow(double).to receive(:msg).and_raise(error)
315 allow(double).to receive(:msg).and_throw(:msg)
86abf8d @myronmarston Fixup README code formatting.
myronmarston authored
316 allow(double).to receive(:msg).and_yield(values, to, yield)
317 allow(double).to receive(:msg).and_yield(values, to, yield).and_yield(some, other, values, this, time)
a13dd64 @icambron added ruby syntax highlighting for github
icambron authored
318 ```
c186d12 @dchelimsky move overview to Readme (where it belongs)
dchelimsky authored
319
320 ## Arbitrary Handling
321
322 Once in a while you'll find that the available expectations don't solve the
323 particular problem you are trying to solve. Imagine that you expect the message
324 to come with an Array argument that has a specific length, but you don't care
325 what is in it. You could do this:
326
a13dd64 @icambron added ruby syntax highlighting for github
icambron authored
327 ```ruby
1f370af @thomas-holmes Update README.md to use expect syntax.
thomas-holmes authored
328 expect(double).to receive(:msg) do |arg|
329 expect(arg.size).to eq 7
f86db3e @icambron removed extra indentation in readme
icambron authored
330 end
a13dd64 @icambron added ruby syntax highlighting for github
icambron authored
331 ```
9d19ca0 @dchelimsky update readme
dchelimsky authored
332
ec9b5e5 @pjambet Use new Codeclimate badge, made by @olivierlacan
pjambet authored
333 If the method being stubbed itself takes a block, and you need to yield to it
56102c1 @goblin add a small example to README
goblin authored
334 in some special way, you can use this:
335
336 ```ruby
1f370af @thomas-holmes Update README.md to use expect syntax.
thomas-holmes authored
337 expect(double).to receive(:msg) do |&arg|
56102c1 @goblin add a small example to README
goblin authored
338 begin
339 arg.call
340 ensure
341 # cleanup
342 end
343 end
344 ```
345
2ab2776 @myronmarston Add `and_call_original` which delegates to the original method.
myronmarston authored
346 ## Delegating to the Original Implementation
347
348 When working with a partial mock object, you may occasionally
349 want to set a message expecation without interfering with how
350 the object responds to the message. You can use `and_call_original`
351 to achieve this:
352
353 ```ruby
1f370af @thomas-holmes Update README.md to use expect syntax.
thomas-holmes authored
354 expect(Person).to receive(:find).and_call_original
2ab2776 @myronmarston Add `and_call_original` which delegates to the original method.
myronmarston authored
355 Person.find # => executes the original find method and returns the result
356 ```
357
c186d12 @dchelimsky move overview to Readme (where it belongs)
dchelimsky authored
358 ## Combining Expectation Details
359
360 Combining the message name with specific arguments, receive counts and responses
361 you can get quite a bit of detail in your expectations:
362
a13dd64 @icambron added ruby syntax highlighting for github
icambron authored
363 ```ruby
1f370af @thomas-holmes Update README.md to use expect syntax.
thomas-holmes authored
364 expect(double).to receive(:<<).with("illegal value").once.and_raise(ArgumentError)
a13dd64 @icambron added ruby syntax highlighting for github
icambron authored
365 ```
c186d12 @dchelimsky move overview to Readme (where it belongs)
dchelimsky authored
366
f4bd883 @dchelimsky rdoc (and a rename or two)
dchelimsky authored
367 While this is a good thing when you really need it, you probably don't really
368 need it! Take care to specify only the things that matter to the behavior of
369 your code.
370
0d6eea7 @myronmarston Fix broken link.
myronmarston authored
371 ## Stubbing and Hiding Constants
ecfb7f6 @myronmarston Add API docs for new constant stubbing code.
myronmarston authored
372
0d6eea7 @myronmarston Fix broken link.
myronmarston authored
373 See the [mutating constants
374 README](https://github.com/rspec/rspec-mocks/blob/master/features/mutating_constants/README.md)
0bd5850 @myronmarston Replace duplicated README content with a link.
myronmarston authored
375 for info on this feature.
ecfb7f6 @myronmarston Add API docs for new constant stubbing code.
myronmarston authored
376
1851678 @myronmarston Use modern scope names for hooks.
myronmarston authored
377 ## Use `before(:example)`, not `before(:context)`
0815a4a @nathanl Explained why `before(:all)` won't work for stubs.
nathanl authored
378
1851678 @myronmarston Use modern scope names for hooks.
myronmarston authored
379 Stubs in `before(:context)` are not supported. The reason is that all stubs and mocks get cleared out after each example, so any stub that is set in `before(:context)` would work in the first example that happens to run in that group, but not for any others.
0815a4a @nathanl Explained why `before(:all)` won't work for stubs.
nathanl authored
380
1851678 @myronmarston Use modern scope names for hooks.
myronmarston authored
381 Instead of `before(:context)`, use `before(:example)`.
0815a4a @nathanl Explained why `before(:all)` won't work for stubs.
nathanl authored
382
d680c26 @thomas-holmes Add section to README for any instance features.
thomas-holmes authored
383 ## Settings mocks or stubs on any instance of a class
384
385 rspec-mocks provides two methods, `allow_any_instance_of` and
386 `expect_any_instance_of`, that will allow you to stub or mock any instance
718bb92 @myronmarston Clarify some docs.
myronmarston authored
387 of a class. They are used in place of `allow` or `expect`:
d680c26 @thomas-holmes Add section to README for any instance features.
thomas-holmes authored
388
389 ```ruby
390 allow_any_instance_of(Widget).to receive(:name).and_return("Wibble")
391 expect_any_instance_of(Widget).to receive(:name).and_return("Wobble")
392 ```
393
394 These methods add the appropriate stub or expectation to all instances of
395 `Widget`.
396
397 This feature is sometimes useful when working with legacy code, though in
398 general we discourage its use for a number of reasons:
399
400 * The `rspec-mocks` API is designed for individual object instances, but this
401 feature operates on entire classes of objects. As a result there are some
f8c1fd8 @imtayadeway Fix typo on README line 380.
imtayadeway authored
402 semantically confusing edge cases. For example in
d680c26 @thomas-holmes Add section to README for any instance features.
thomas-holmes authored
403 `expect_any_instance_of(Widget).to receive(:name).twice` it isn't clear
718bb92 @myronmarston Clarify some docs.
myronmarston authored
404 whether each specific instance is expected to receive `name` twice, or if two
405 receives total are expected. (It's the former.)
d680c26 @thomas-holmes Add section to README for any instance features.
thomas-holmes authored
406 * Using this feature is often a design smell. It may be
407 that your test is trying to do too much or that the object under test is too
408 complex.
409 * It is the most complicated feature of `rspec-mocks`, and has historically
410 received the most bug reports. (None of the core team actively use it,
411 which doesn't help.)
412
413
c186d12 @dchelimsky move overview to Readme (where it belongs)
dchelimsky authored
414 ## Further Reading
415
f4bd883 @dchelimsky rdoc (and a rename or two)
dchelimsky authored
416 There are many different viewpoints about the meaning of mocks and stubs. If
417 you are interested in learning more, here is some recommended reading:
c186d12 @dchelimsky move overview to Readme (where it belongs)
dchelimsky authored
418
419 * Mock Objects: http://www.mockobjects.com/
ad0c0ac @nicholasjhenry Fix broken links in 'Further Reading'
nicholasjhenry authored
420 * Endo-Testing: http://www.ccs.neu.edu/research/demeter/related-work/extreme-programming/MockObjectsFinal.PDF
421 * Mock Roles, Not Objects: http://www.jmock.org/oopsla2004.pdf
839cf33 @maxlinc Add link to Test Double bliki
maxlinc authored
422 * Test Double: http://www.martinfowler.com/bliki/TestDouble.html
c186d12 @dchelimsky move overview to Readme (where it belongs)
dchelimsky authored
423 * Test Double Patterns: http://xunitpatterns.com/Test%20Double%20Patterns.html
424 * Mocks aren't stubs: http://www.martinfowler.com/articles/mocksArentStubs.html
425
f26af00 @dchelimsky words
dchelimsky authored
426 ## Also see
9d19ca0 @dchelimsky update readme
dchelimsky authored
427
f9f8418 @dchelimsky words
dchelimsky authored
428 * [http://github.com/rspec/rspec](http://github.com/rspec/rspec)
429 * [http://github.com/rspec/rspec-core](http://github.com/rspec/rspec-core)
430 * [http://github.com/rspec/rspec-expectations](http://github.com/rspec/rspec-expectations)
Something went wrong with that request. Please try again.