flexmock 1.2.0 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +3 -0
- data/Gemfile.lock +57 -0
- data/{README.rdoc → README.md} +376 -247
- data/Rakefile +5 -5
- data/doc/index.rdoc +31 -0
- data/doc/releases/flexmock-1.0.0.rdoc +2 -2
- data/doc/releases/flexmock-1.0.4.rdoc +165 -0
- data/doc/releases/flexmock-1.1.0.rdoc +144 -0
- data/doc/releases/flexmock-1.2.0.rdoc +150 -0
- data/doc/releases/flexmock-1.3.0.rdoc +165 -0
- data/lib/flexmock/core.rb +24 -3
- data/lib/flexmock/rspec_spy_matcher.rb +21 -3
- data/lib/flexmock/version.rb +1 -1
- data/test/rspec_integration/spy_example_spec.rb +73 -7
- data/test/spys_test.rb +53 -0
- metadata +14 -5
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,11 +1,56 @@
|
|
1
1
|
GEM
|
2
2
|
remote: http://rubygems.org/
|
3
3
|
specs:
|
4
|
+
activesupport (3.2.11)
|
5
|
+
i18n (~> 0.6)
|
6
|
+
multi_json (~> 1.0)
|
7
|
+
blankslate (3.1.2)
|
8
|
+
charlock_holmes (0.6.9)
|
4
9
|
diff-lcs (1.1.3)
|
10
|
+
escape_utils (0.2.4)
|
11
|
+
ffi (1.0.11)
|
12
|
+
flay (2.0.1)
|
13
|
+
ruby_parser (~> 3.0)
|
14
|
+
sexp_processor (~> 4.0)
|
15
|
+
flog (3.2.2)
|
16
|
+
ruby_parser (~> 3.1, > 3.1.0)
|
17
|
+
sexp_processor (~> 4.0)
|
18
|
+
gemoji (1.4.0)
|
19
|
+
ghpreview (0.0.6)
|
20
|
+
github-linguist (= 2.1)
|
21
|
+
html-pipeline (= 0.0.6)
|
22
|
+
httpclient
|
23
|
+
listen
|
24
|
+
rb-fsevent
|
25
|
+
github-linguist (2.1.0)
|
26
|
+
charlock_holmes (~> 0.6.6)
|
27
|
+
escape_utils (~> 0.2.3)
|
28
|
+
mime-types (~> 1.18)
|
29
|
+
pygments.rb (~> 0.2.13)
|
30
|
+
github-markdown (0.5.3)
|
31
|
+
html-pipeline (0.0.6)
|
32
|
+
activesupport (>= 2)
|
33
|
+
escape_utils (~> 0.2)
|
34
|
+
gemoji (~> 1.0)
|
35
|
+
github-linguist (~> 2.1)
|
36
|
+
github-markdown (~> 0.5)
|
37
|
+
nokogiri (~> 1.4)
|
38
|
+
rinku (~> 1.7)
|
39
|
+
sanitize (~> 2.0)
|
40
|
+
httpclient (2.3.2)
|
41
|
+
i18n (0.6.1)
|
5
42
|
json (1.7.5)
|
43
|
+
listen (0.7.2)
|
44
|
+
mime-types (1.19)
|
45
|
+
multi_json (1.5.0)
|
46
|
+
nokogiri (1.5.6)
|
47
|
+
pygments.rb (0.2.13)
|
48
|
+
rubypython (~> 0.5.3)
|
6
49
|
rake (0.9.2.2)
|
50
|
+
rb-fsevent (0.9.3)
|
7
51
|
rdoc (3.12)
|
8
52
|
json (~> 1.4)
|
53
|
+
rinku (1.7.2)
|
9
54
|
rspec (2.11.0)
|
10
55
|
rspec-core (~> 2.11.0)
|
11
56
|
rspec-expectations (~> 2.11.0)
|
@@ -14,11 +59,23 @@ GEM
|
|
14
59
|
rspec-expectations (2.11.2)
|
15
60
|
diff-lcs (~> 1.1.3)
|
16
61
|
rspec-mocks (2.11.2)
|
62
|
+
ruby_parser (3.1.1)
|
63
|
+
sexp_processor (~> 4.1)
|
64
|
+
rubypython (0.5.3)
|
65
|
+
blankslate (>= 2.1.2.3)
|
66
|
+
ffi (~> 1.0.7)
|
67
|
+
sanitize (2.0.3)
|
68
|
+
nokogiri (>= 1.4.4, < 1.6)
|
69
|
+
nokogiri (>= 1.4.4, < 1.6)
|
70
|
+
sexp_processor (4.1.4)
|
17
71
|
|
18
72
|
PLATFORMS
|
19
73
|
ruby
|
20
74
|
|
21
75
|
DEPENDENCIES
|
76
|
+
flay
|
77
|
+
flog
|
78
|
+
ghpreview
|
22
79
|
rake (>= 0.9.2.2)
|
23
80
|
rdoc
|
24
81
|
rspec (>= 2.0)
|
data/{README.rdoc → README.md}
RENAMED
@@ -1,34 +1,37 @@
|
|
1
|
-
|
1
|
+
# Flex Mock -- Making Mocking Easy
|
2
2
|
|
3
3
|
FlexMock is a simple, but flexible, mock object library for Ruby unit
|
4
4
|
testing.
|
5
5
|
|
6
|
-
Version
|
6
|
+
Version: 1.3.0
|
7
7
|
|
8
|
-
|
8
|
+
# Links
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
10
|
+
* **Documents** -- http://flexmock.rubyforge.org
|
11
|
+
* **RubyGems** -- Install with: `gem install flexmock`
|
12
|
+
* **Source** -- https://github.com/jimweirich/flexmock
|
13
|
+
* **Bug Reports / Issue Tracking** -- https://github.com/jimweirich/flexmock/issues
|
14
|
+
* **Continuous Integration** -- http://travis-ci.org/#!/jimweirich/flexmock
|
15
15
|
|
16
|
-
|
16
|
+
## Installation
|
17
17
|
|
18
18
|
You can install FlexMock with the following command.
|
19
19
|
|
20
|
+
```
|
20
21
|
$ gem install flexmock
|
22
|
+
```
|
21
23
|
|
22
|
-
|
24
|
+
## Simple Example
|
23
25
|
|
24
26
|
We have a data acquisition class (<code>TemperatureSampler</code>)
|
25
27
|
that reads a temperature sensor and returns an average of 3 readings.
|
26
28
|
We don't have a _real_ temperature to use for testing, so we mock one
|
27
29
|
up with a mock object that responds to the
|
28
|
-
|
30
|
+
`read_temperature` message.
|
29
31
|
|
30
32
|
Here's the complete example:
|
31
33
|
|
34
|
+
```ruby
|
32
35
|
require 'test/unit'
|
33
36
|
require 'flexmock/test_unit'
|
34
37
|
|
@@ -55,20 +58,23 @@ Here's the complete example:
|
|
55
58
|
assert_equal 12, sampler.average_temp
|
56
59
|
end
|
57
60
|
end
|
61
|
+
```
|
58
62
|
|
59
|
-
You can find an extended example of FlexMock in
|
60
|
-
Example
|
63
|
+
You can find an extended example of FlexMock in
|
64
|
+
[Google Example](http://flexmock.rubyforge.org/files/doc/GoogleExample_rdoc.html
|
65
|
+
"Example").
|
61
66
|
|
62
|
-
|
67
|
+
## Test::Unit Integration
|
63
68
|
|
64
69
|
FlexMock integrates nicely with Test::Unit. Just require the
|
65
70
|
'flexmock/test_unit' file at the top of your test file. The
|
66
|
-
|
71
|
+
`flexmock` method will be available for mock creation, and
|
67
72
|
any created mocks will be automatically validated and closed at the
|
68
73
|
end of the individual test.
|
69
74
|
|
70
75
|
Your test case will look something like this:
|
71
76
|
|
77
|
+
```ruby
|
72
78
|
require 'flexmock/test_unit'
|
73
79
|
|
74
80
|
class TestDog < Test::Unit::TestCase
|
@@ -77,19 +83,21 @@ Your test case will look something like this:
|
|
77
83
|
assert_equal :happy, tail_mock.wag
|
78
84
|
end
|
79
85
|
end
|
86
|
+
```
|
80
87
|
|
81
|
-
|
88
|
+
**NOTE:** If you don't want to automatically extend every TestCase
|
82
89
|
with the flexmock methods and overhead, then require the 'flexmock'
|
83
90
|
file and explicitly include the FlexMock::TestCase module in each test
|
84
91
|
case class where you wish to use mock objects. FlexMock versions prior
|
85
92
|
to 0.6.0 required the explicit include.
|
86
93
|
|
87
|
-
|
94
|
+
## RSpec Integration
|
88
95
|
|
89
96
|
FlexMock also supports integration with the RSpec behavior
|
90
97
|
specification framework. Starting with version 0.9.0 of RSpec, you
|
91
98
|
will be able to say:
|
92
99
|
|
100
|
+
```ruby
|
93
101
|
RSpec.configure do |config|
|
94
102
|
config.mock_with :flexmock
|
95
103
|
end
|
@@ -100,21 +108,24 @@ will be able to say:
|
|
100
108
|
m.foo.should === :bar
|
101
109
|
end
|
102
110
|
end
|
111
|
+
```
|
103
112
|
|
104
|
-
|
113
|
+
**NOTE:** _Older versions of RSpec used the Spec::Runner for
|
105
114
|
configuration. If you are running with a very old RSpec, you may need
|
106
|
-
the following
|
115
|
+
the following:_
|
107
116
|
|
117
|
+
```ruby
|
108
118
|
# Configuration for RSpec prior to RSpec 2.x
|
109
119
|
Spec::Runner.configure do |config|
|
110
120
|
config.mock_with :flexmock
|
111
121
|
end
|
122
|
+
```
|
112
123
|
|
113
|
-
|
124
|
+
## Quick Reference
|
114
125
|
|
115
|
-
|
126
|
+
### Creating Mock Objects
|
116
127
|
|
117
|
-
The
|
128
|
+
The `flexmock` method is used to create mocks in various
|
118
129
|
configurations. Here's a quick rundown of the most common options. See
|
119
130
|
FlexMock::MockContainer#flexmock for more details.
|
120
131
|
|
@@ -134,7 +145,7 @@ FlexMock::MockContainer#flexmock for more details.
|
|
134
145
|
You can combine the mock name and an expectation hash in the same
|
135
146
|
call to flexmock.
|
136
147
|
|
137
|
-
* <b>mock = flexmock("joe", :on, User)</b>
|
148
|
+
* <b>mock = flexmock("joe", :on, <em>User</em>)</b>
|
138
149
|
|
139
150
|
This defines a mock that is based on the User class (the class is
|
140
151
|
called the mock's "base class"). Mocks with base classes prevent you
|
@@ -142,29 +153,28 @@ FlexMock::MockContainer#flexmock for more details.
|
|
142
153
|
the base class. This helps prevent tests from becoming stale with
|
143
154
|
incorrectly mocked objects when the method names change.
|
144
155
|
|
145
|
-
Use the
|
146
|
-
|
156
|
+
Use the `explicitly` modifier to `should_receive` to override base
|
157
|
+
class restrictions.
|
147
158
|
|
148
|
-
* <b>partial_mock = flexmock(real_object)</b>
|
159
|
+
* <b>partial_mock = flexmock(<em>real_object</em>)</b>
|
149
160
|
|
150
|
-
If you you give
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
portion of the test.
|
161
|
+
If you you give `flexmock` a real object in the argument list, it
|
162
|
+
will treat that real object as a base for a partial mock object. The
|
163
|
+
return value `partial_mock` may be used to set expectations. The
|
164
|
+
real_object should be used in the reference portion of the test.
|
155
165
|
|
156
|
-
* <b>partial_mock = flexmock(real_object
|
166
|
+
* <b>partial_mock = flexmock(<em>real_object</em>, "name", :foo => :baz)</b>
|
157
167
|
|
158
168
|
Names and expectation hashes may be used with partial mocks as well.
|
159
169
|
|
160
|
-
* <b>partial_mock = flexmock(:base, real_string_object)</b>
|
170
|
+
* <b>partial_mock = flexmock(:base, <em>real_string_object</em>)</b>
|
161
171
|
|
162
172
|
Since Strings (and Symbols for that matter) are used for mock names,
|
163
173
|
FlexMock will not recognize them as the base for a partial mock. To
|
164
174
|
force a string to be used as a partial mock base, proceed the string
|
165
175
|
object in the calling sequence with :base.
|
166
176
|
|
167
|
-
* <b>partial_mock = flexmock(:safe, real_object) { |mock| mock.should_receive(...) }</b>
|
177
|
+
* <b>partial_mock = flexmock(:safe, <em>real_object</em>) { |mock| mock.should_receive(...) }</b>
|
168
178
|
|
169
179
|
When mocking real objects (i.e. "partial mocks"), FlexMock will add
|
170
180
|
a handful of mock related methods to the actual object (see below
|
@@ -174,9 +184,9 @@ FlexMock::MockContainer#flexmock for more details.
|
|
174
184
|
|
175
185
|
FlexMock offers a "safe" mode for partial mocks that does not add
|
176
186
|
these methods. Indicate safe mode by passing the symbol :safe as the
|
177
|
-
first argument of flexmock. A block
|
178
|
-
|
179
|
-
|
187
|
+
first argument of flexmock. A block _is required_ when using safe
|
188
|
+
mode (the partial_mock returned in safe mode does not have a
|
189
|
+
`should_receive` method).
|
180
190
|
|
181
191
|
The methods added to partial mocks in non-safe mode are:
|
182
192
|
|
@@ -190,19 +200,19 @@ FlexMock::MockContainer#flexmock for more details.
|
|
190
200
|
|
191
201
|
* <b>mock = flexmock(...) { |mock| mock.should_receive(...) }</b>
|
192
202
|
|
193
|
-
If a block is given to any of the
|
194
|
-
|
195
|
-
|
203
|
+
If a block is given to any of the `flexmock` forms, the mock object
|
204
|
+
will be passed to the block as an argument. Code in the block can
|
205
|
+
set the desired expectations for the mock object.
|
196
206
|
|
197
|
-
* <b>mock_model = flexmock(:model, YourModel
|
207
|
+
* <b>mock_model = flexmock(:model, <em>YourModel</em>, ...) { |mock| mock.should_receive(...) }</b>
|
198
208
|
|
199
|
-
When given
|
200
|
-
mock) that will have some ActiveRecord specific methods
|
201
|
-
YourModel should be the class of an ActiveRecord model.
|
202
|
-
predefined methods make it a bit easier to mock out
|
203
|
-
model objects in a Rails application.
|
204
|
-
mocked methods, the mock returned is a standard FlexMock
|
205
|
-
object.
|
209
|
+
When given `:model`, `flexmock()` will return a pure mock (not a
|
210
|
+
partial mock) that will have some ActiveRecord specific methods
|
211
|
+
defined. YourModel should be the class of an ActiveRecord model.
|
212
|
+
These predefined methods make it a bit easier to mock out
|
213
|
+
ActiveRecord model objects in a Rails application. Other that the
|
214
|
+
predefined mocked methods, the mock returned is a standard FlexMock
|
215
|
+
mock object.
|
206
216
|
|
207
217
|
The predefined mocked methods are:
|
208
218
|
|
@@ -215,44 +225,48 @@ FlexMock::MockContainer#flexmock for more details.
|
|
215
225
|
* kind_of?(class) -- returns true if class is YourModel or one of its ancestors
|
216
226
|
* class -- returns YourModel.
|
217
227
|
|
218
|
-
* <b>mock = flexmock(... :
|
228
|
+
* <b>mock = flexmock(... :on, <em>class_object</em>, ...)</b>
|
219
229
|
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
230
|
+
**NOTE:** Versions of FlexMock prior to 0.6.0 used `flexstub` to
|
231
|
+
create partial mocks. The `flexmock` method now assumes all the
|
232
|
+
functionality that was spread out between two different methods.
|
233
|
+
`flexstub` is deprecated, but still available for backward
|
234
|
+
compatibility.
|
225
235
|
|
226
|
-
|
236
|
+
### Expectation Declarators
|
227
237
|
|
228
238
|
Once a mock is created, you need to define what that mock should
|
229
239
|
expect to see. Expectation declarators are used to specify these
|
230
240
|
expectations placed upon received method calls. A basic expectation,
|
231
|
-
created with the
|
232
|
-
|
241
|
+
created with the `should_receive` method, just establishes the fact
|
242
|
+
that a method may (or may not) be called on the mock object.
|
233
243
|
Refinements to that expectation may be additionally declared. FlexMock
|
234
244
|
always starts with the most general expectation and adds constraints
|
235
245
|
to that.
|
236
246
|
|
237
247
|
For example, the following code:
|
238
248
|
|
249
|
+
```ruby
|
239
250
|
mock.should_receive(:average).and_return(12)
|
251
|
+
```
|
240
252
|
|
241
253
|
Means that the mock will now accept method calls to an
|
242
|
-
|
254
|
+
`average` method. The expectation will accept any arguments
|
243
255
|
and may be called any number of times (including zero times). Strictly
|
244
|
-
speaking, the
|
256
|
+
speaking, the `and_return` part of the declaration isn't
|
245
257
|
exactly a constraint, but it does specify what value the mock will
|
246
258
|
return when the expectation is matched.
|
247
259
|
|
248
260
|
If you want to be more specific, you need to add additional
|
249
261
|
constraints to your expectation. Here are some examples:
|
250
262
|
|
263
|
+
```ruby
|
251
264
|
mock.should_receive(:average).with(12).once
|
252
265
|
|
253
266
|
mock.should_receive(:average).with(Integer).
|
254
267
|
at_least.twice.at_most.times(10).
|
255
268
|
and_return { rand }
|
269
|
+
```
|
256
270
|
|
257
271
|
Expectation are always matched in order of declaration. That means if
|
258
272
|
you have a general expectation before a more specific expectation, the
|
@@ -261,8 +275,10 @@ effectively hiding the second expectation.
|
|
261
275
|
|
262
276
|
For example:
|
263
277
|
|
278
|
+
```ruby
|
264
279
|
mock.should_receive(:average) # Matches any call to average
|
265
280
|
mock.should_receive(:average).with(1).once # Fails because it never matches
|
281
|
+
```
|
266
282
|
|
267
283
|
In the example, the second expectation will never be triggered because
|
268
284
|
all calls to average will be handled by the first expectation. Since
|
@@ -272,15 +288,17 @@ fail.
|
|
272
288
|
Reversing the order of the expections so that the more specific
|
273
289
|
expectation comes first will fix that problem.
|
274
290
|
|
275
|
-
If an expectation has a count requirement (e.g.
|
276
|
-
|
277
|
-
|
291
|
+
If an expectation has a count requirement (e.g. `once` or `times`),
|
292
|
+
then once it has matched its expected number of times, it will let
|
293
|
+
other expectations have a chance to match.
|
278
294
|
|
279
295
|
For example:
|
280
296
|
|
297
|
+
```ruby
|
281
298
|
mock.should_receive(:average).once.and_return(1)
|
282
299
|
mock.should_receive(:average).once.and_return(2)
|
283
300
|
mock.should_receive(:average).and_return(3)
|
301
|
+
```
|
284
302
|
|
285
303
|
In the example, the first time average is called, the first
|
286
304
|
expectation is matched an average will return 1. The second time
|
@@ -290,21 +308,20 @@ will be used.
|
|
290
308
|
|
291
309
|
Occasionally it is useful define a set of expecations in a setup
|
292
310
|
method of a test and override those expectations in specific tests. If
|
293
|
-
you mark an expectation with the
|
294
|
-
|
295
|
-
|
311
|
+
you mark an expectation with the `by_default` marker, that expectation
|
312
|
+
will be used only if there are no non-default expectations on that
|
313
|
+
method name. See "by_default" below.
|
296
314
|
|
297
|
-
|
315
|
+
### Expectation Criteria
|
298
316
|
|
299
317
|
The following methods may be used to create and refine expectations on
|
300
318
|
a mock object. See theFlexMock::Expectation for more details.
|
301
319
|
|
302
320
|
* <b>should_receive(<em>method_name</em>)</b>
|
303
321
|
|
304
|
-
Declares that a message named
|
305
|
-
|
306
|
-
|
307
|
-
call.
|
322
|
+
Declares that a message named _method_name_ will be sent to the mock
|
323
|
+
object. Constraints on this expected message (called expectations)
|
324
|
+
may be chained to the `should_receive` call.
|
308
325
|
|
309
326
|
* <b>should_receive(<em>method_name1</em>, <em>method_name2</em>, ...)</b>
|
310
327
|
|
@@ -317,11 +334,10 @@ a mock object. See theFlexMock::Expectation for more details.
|
|
317
334
|
|
318
335
|
* <b>should_receive(...).explicitly</b>
|
319
336
|
|
320
|
-
If a mock has a base class, use the
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
expectation declarators.
|
337
|
+
If a mock has a base class, use the `explicitly` modifier to
|
338
|
+
override the restriction on method names imposed by the base class.
|
339
|
+
The `explicitly` modifier must come immediately after the
|
340
|
+
`should_receive` call and before any other expectation declarators.
|
325
341
|
|
326
342
|
If a mock does not have a base class, this method has no effect.
|
327
343
|
|
@@ -329,18 +345,18 @@ a mock object. See theFlexMock::Expectation for more details.
|
|
329
345
|
|
330
346
|
Creates a mock recording object that will translate received method
|
331
347
|
calls into mock expectations. The recorder is passed to a block
|
332
|
-
supplied with the
|
348
|
+
supplied with the `should_expect` method. See examples
|
333
349
|
below.
|
334
350
|
|
335
351
|
* <b>with(<em>arglist</em>)</b>
|
336
352
|
|
337
353
|
Declares that this expectation matches messages that match the given
|
338
|
-
argument list. The
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
354
|
+
argument list. The `===` operator is used on a argument by argument
|
355
|
+
basis to determine matching. This means that most literal values
|
356
|
+
match literally, class values match any instance of a class and
|
357
|
+
regular expression match any matching string (after a `to_s`
|
358
|
+
conversion). See argument validators (below) for details on argument
|
359
|
+
validation options.
|
344
360
|
|
345
361
|
* <b>with_any_args</b>
|
346
362
|
|
@@ -354,41 +370,41 @@ a mock object. See theFlexMock::Expectation for more details.
|
|
354
370
|
* <b>zero_or_more_times</b>
|
355
371
|
|
356
372
|
Declares that the expected message is may be sent zero or more times
|
357
|
-
(default, equivalent to
|
373
|
+
(default, equivalent to `at_least.never`).
|
358
374
|
|
359
375
|
* <b>once</b>
|
360
376
|
|
361
|
-
Declares that the expected message is only sent once.
|
362
|
-
|
377
|
+
Declares that the expected message is only sent once. `at_least` /
|
378
|
+
`at_most` modifiers are allowed.
|
363
379
|
|
364
380
|
* <b>twice</b>
|
365
381
|
|
366
|
-
Declares that the expected message is only sent twice.
|
367
|
-
|
382
|
+
Declares that the expected message is only sent twice. `at_least` /
|
383
|
+
`at_most` modifiers are allowed.
|
368
384
|
|
369
385
|
* <b>never</b>
|
370
386
|
|
371
|
-
Declares that the expected message is never sent.
|
372
|
-
|
387
|
+
Declares that the expected message is never sent. `at_least` /
|
388
|
+
`at_most` modifiers are allowed.
|
373
389
|
|
374
390
|
* <b>times(<em>n</em>)</b>
|
375
391
|
|
376
|
-
Declares that the expected message is sent
|
377
|
-
|
392
|
+
Declares that the expected message is sent _n_ times. `at_least` /
|
393
|
+
`at_most` modifiers are allowed.
|
378
394
|
|
379
395
|
* <b>at_least</b>
|
380
396
|
|
381
397
|
Modifies the immediately following message count constraint so that
|
382
398
|
it means the message is sent at least that number of times. E.g.
|
383
|
-
|
384
|
-
|
385
|
-
|
399
|
+
`at_least.once` means the message is sent at least once during the
|
400
|
+
test, but may be sent more often. Both `at_least` and `at_most` may
|
401
|
+
be specified on the same expectation.
|
386
402
|
|
387
403
|
* <b>at_most</b>
|
388
404
|
|
389
|
-
Similar to
|
390
|
-
|
391
|
-
|
405
|
+
Similar to `at_least`, but puts an upper limit on the number of
|
406
|
+
messages. Both `at_least` and `at_most` may be specified on the same
|
407
|
+
expectation.
|
392
408
|
|
393
409
|
* <b>ordered</b>
|
394
410
|
|
@@ -409,18 +425,19 @@ a mock object. See theFlexMock::Expectation for more details.
|
|
409
425
|
outside the group must be received either before or after all of the
|
410
426
|
grouped messages.
|
411
427
|
|
412
|
-
For example, in the following, messages
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
be received at any time because it is not ordered.
|
428
|
+
For example, in the following, messages `flip` and `flop` may be
|
429
|
+
received in any order (because they are in the same group), but must
|
430
|
+
occur strictly after `start` but before `end`. The message
|
431
|
+
`any_time` may be received at any time because it is not ordered.
|
417
432
|
|
433
|
+
```ruby
|
418
434
|
m = flexmock()
|
419
435
|
m.should_receive(:any_time)
|
420
436
|
m.should_receive(:start).ordered
|
421
437
|
m.should_receive(:flip).ordered(:flip_flop_group)
|
422
438
|
m.should_receive(:flop).ordered(:flip_flop_group)
|
423
439
|
m.should_receive(:end).ordered
|
440
|
+
```
|
424
441
|
|
425
442
|
Normally ordering is performed only against calls in the same mock
|
426
443
|
object. If the "globally" adjective is used, then ordering is
|
@@ -446,12 +463,11 @@ a mock object. See theFlexMock::Expectation for more details.
|
|
446
463
|
for various methods in the setup of a test suite, and then override
|
447
464
|
only the methods that need special handling in any given test.
|
448
465
|
|
449
|
-
|
466
|
+
### Expectation Actions
|
450
467
|
|
451
|
-
Action expectations are used to specify what the mock should
|
452
|
-
|
453
|
-
|
454
|
-
not.
|
468
|
+
Action expectations are used to specify what the mock should _do_ when
|
469
|
+
the expectation is matched. The actions themselves do not take part in
|
470
|
+
determining whether a given expectation matches or not.
|
455
471
|
|
456
472
|
* <b>and_return(<em>value</em>)</b>
|
457
473
|
|
@@ -464,7 +480,7 @@ not.
|
|
464
480
|
series. The last value will be repeatably returned if the number of
|
465
481
|
matching calls exceeds the number of values.
|
466
482
|
|
467
|
-
* <b>and_return { |<em>args</em>, ...| <em>code</em> ... }
|
483
|
+
* <b>and_return { |<em>args</em>, ...| <em>code</em> ... }</b>
|
468
484
|
|
469
485
|
Declares that the expected message will return the yielded value of
|
470
486
|
the block. The block will receive all the arguments in the message.
|
@@ -473,7 +489,7 @@ not.
|
|
473
489
|
|
474
490
|
* <b>returns( ... )</b>
|
475
491
|
|
476
|
-
Alias for
|
492
|
+
Alias for `and_return`.
|
477
493
|
|
478
494
|
* <b>and_return_undefined</b>
|
479
495
|
|
@@ -482,20 +498,19 @@ not.
|
|
482
498
|
|
483
499
|
* <b>returns_undefined</b>
|
484
500
|
|
485
|
-
Alias for
|
501
|
+
Alias for `and_returns_undefined`
|
486
502
|
|
487
|
-
* <b>and_raise(
|
503
|
+
* <b>and_raise(_exception_, _*args_)</b>
|
488
504
|
|
489
505
|
Declares that the expected message will raise the specified
|
490
|
-
exception. If
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
will be raised directly.
|
506
|
+
exception. If `exception` is an exception class, then the raised
|
507
|
+
exception will be constructed from the class with `new` given the
|
508
|
+
supplied arguments. If `exception` is an instance of an exception
|
509
|
+
class, then it will be raised directly.
|
495
510
|
|
496
511
|
* <b>raises( ... )</b>
|
497
512
|
|
498
|
-
Alias for
|
513
|
+
Alias for `and_raise`.
|
499
514
|
|
500
515
|
* <b>and_throw(<em>symbol</em>)</b>
|
501
516
|
* <b>and_throw(<em>symbol</em>, <em>value</em>)</b>
|
@@ -506,86 +521,95 @@ not.
|
|
506
521
|
|
507
522
|
* <b>throws( ... )</b>
|
508
523
|
|
509
|
-
Alias for
|
524
|
+
Alias for `and_throw`.
|
510
525
|
|
511
526
|
* <b>and_yield(<em>values</em>, ...)</b>
|
512
527
|
|
513
528
|
Declares that the mocked method will receive a block, and the mock
|
514
529
|
will call that block with the values given. Not providing a block
|
515
|
-
will be an error. Providing more than one
|
516
|
-
|
517
|
-
|
518
|
-
<code>and_yield</code> clause.
|
530
|
+
will be an error. Providing more than one `and_yield` clause one a
|
531
|
+
single expectation will mean that subsquent mock method calls will
|
532
|
+
yield the values provided by the additional `and_yield` clause.
|
519
533
|
|
520
534
|
* <b>yields( ... )</b>
|
521
535
|
|
522
|
-
Alias for
|
536
|
+
Alias for `and_yield( ... )`.
|
523
537
|
|
524
538
|
* <b>pass_thru</b>
|
525
|
-
* <b>pass_thru {
|
539
|
+
* <b>pass_thru { |<em>value</em>| .... }</b>
|
526
540
|
|
527
541
|
Declares that the expected message will allow the method to be
|
528
542
|
passed to the original method definition in the partial mock object.
|
529
|
-
|
530
|
-
|
531
|
-
|
543
|
+
`pass_thru` is also allowed on regular mocks, but since there is no
|
544
|
+
original method to be called, pass_thru will always return the
|
545
|
+
undefined object.
|
532
546
|
|
533
|
-
If a block is supplied to pass_thru
|
547
|
+
If a block is supplied to `pass_thru`, the value returned from the
|
534
548
|
original method will be passed to the block and the value of the
|
535
549
|
block will be returned. This allows you to mock methods on the
|
536
550
|
returned value.
|
537
551
|
|
552
|
+
```ruby
|
538
553
|
Dog.should_receive(:new).pass_thru { |dog|
|
539
554
|
flexmock(dog, :wag => true)
|
540
555
|
}
|
556
|
+
```
|
541
557
|
|
542
|
-
|
558
|
+
### Other Expectation Methods
|
543
559
|
|
544
560
|
* <b>mock</b>
|
545
561
|
|
546
562
|
Expectation constraints always return the expectation so that the
|
547
563
|
constraints can be chained. If you wish to do a one-liner and assign
|
548
|
-
the mock to a variable, the
|
549
|
-
|
564
|
+
the mock to a variable, the `mock` method on an expectation will
|
565
|
+
return the original mock object.
|
550
566
|
|
567
|
+
```ruby
|
551
568
|
m = flexmock.should_receive(:hello).once.and_return("World").mock
|
569
|
+
```
|
552
570
|
|
553
|
-
|
571
|
+
**NOTE:** _Using **mock** when specifying a Demeter mock
|
554
572
|
chain will return the last mock of the chain, which might not be
|
555
|
-
what you expect
|
573
|
+
what you expect._
|
556
574
|
|
557
|
-
|
575
|
+
### Argument Validation
|
558
576
|
|
559
|
-
The values passed to the
|
560
|
-
|
561
|
-
|
562
|
-
|
577
|
+
The values passed to the `with` declarator determine the criteria for
|
578
|
+
matching expectations. The first expectation found that matches the
|
579
|
+
arguments in a mock method call will be used to validate that mock
|
580
|
+
method call.
|
563
581
|
|
564
582
|
The following rules are used for argument matching:
|
565
583
|
|
566
|
-
* A
|
584
|
+
* A `with` parameter that is a class object will match any
|
567
585
|
actual argument that is an instance of that class.
|
568
586
|
|
569
587
|
Examples:
|
570
588
|
|
589
|
+
```ruby
|
571
590
|
with(Integer) will match f(3)
|
591
|
+
```
|
572
592
|
|
573
593
|
* A regular expression will match any actual argument that matches the
|
574
594
|
regular expression. Non-string actual arguments are converted to
|
575
|
-
strings via
|
595
|
+
strings via `to_s` before applying the regular
|
576
596
|
expression.
|
577
597
|
|
578
598
|
Examples:
|
579
599
|
|
600
|
+
```ruby
|
580
601
|
with(/^src/) will match f("src_object")
|
581
602
|
with(/^3\./) will match f(3.1415972)
|
603
|
+
```
|
582
604
|
|
583
605
|
* Most other objects will match based on equal values.
|
584
606
|
|
585
607
|
Examples:
|
586
608
|
|
609
|
+
```ruby
|
587
610
|
with(3) will match f(3)
|
588
611
|
with("hello") will match f("hello")
|
612
|
+
```
|
589
613
|
|
590
614
|
* If you wish to override the default matching behavior and force
|
591
615
|
matching by equality, you can use the FlexMock.eq convenience
|
@@ -595,79 +619,97 @@ The following rules are used for argument matching:
|
|
595
619
|
|
596
620
|
Examples:
|
597
621
|
|
622
|
+
```ruby
|
598
623
|
with(eq(Integer)) will match f(Integer)
|
599
624
|
with(eq(Integer)) will NOT match f(3)
|
625
|
+
```
|
600
626
|
|
601
|
-
<
|
627
|
+
**Note:** <em>If you do not use the FlexMock::TestCase Test Unit
|
602
628
|
integration module, or the FlexMock::ArgumentTypes module, you will
|
603
|
-
have to fully qualify the
|
604
|
-
|
605
|
-
|
629
|
+
have to fully qualify the `eq` method. This is true of all the
|
630
|
+
special argument matches (`eq`, `on`, `any`, `hsh` and
|
631
|
+
`ducktype`).</em>
|
606
632
|
|
633
|
+
```ruby
|
607
634
|
with(FlexMock.eq(Integer))
|
608
635
|
with(FlexMock.on { code })
|
609
636
|
with(FlexMock.any)
|
610
637
|
with(FlexMock.hsh(:tag => 3))
|
611
638
|
with(FlexMock.ducktype(:wag, :bark))
|
639
|
+
```
|
612
640
|
|
613
641
|
* If you wish to match a hash on _some_ of its values, the
|
614
|
-
FlexMock.hsh(...) method will work.
|
642
|
+
`FlexMock.hsh(...)` method will work. Only specify the hash values
|
615
643
|
you are interested in, the others will be ignored.
|
616
644
|
|
645
|
+
```ruby
|
617
646
|
with(hsh(:run => true)) will match f(:run => true, :stop => false)
|
647
|
+
```
|
618
648
|
|
619
649
|
* If you wish to match any object that responds to a certain set of
|
620
|
-
methods, use the FlexMock.ducktype method.
|
650
|
+
methods, use the `FlexMock.ducktype` method.
|
621
651
|
|
652
|
+
|
653
|
+
```ruby
|
622
654
|
with(ducktype(:to_str)) will match f("string")
|
623
655
|
with(ducktype(:wag, :bark)) will match f(dog)
|
624
656
|
(assuming dog implements wag and bark)
|
657
|
+
```
|
625
658
|
|
626
|
-
* If you wish to match _anything_, then use the
|
627
|
-
|
659
|
+
* If you wish to match _anything_, then use the `FlexMock.any` method
|
660
|
+
in the with argument list.
|
628
661
|
|
629
662
|
Examples (assumes either the FlexMock::TestCase or FlexMock::ArgumentTypes
|
630
663
|
mix-ins has been included):
|
631
664
|
|
665
|
+
```ruby
|
632
666
|
with(any) will match f(3)
|
633
667
|
with(any) will match f("hello")
|
634
668
|
with(any) will match f(Integer)
|
635
669
|
with(any) will match f(nil)
|
670
|
+
```
|
636
671
|
|
637
672
|
* If you wish to specify a complex matching criteria, use the
|
638
|
-
|
673
|
+
`FlexMock.on(&block)` with the logic contained in the block.
|
639
674
|
|
640
|
-
Examples (assumes FlexMock::ArgumentTypes has been included):
|
675
|
+
Examples (assumes `FlexMock::ArgumentTypes` has been included):
|
641
676
|
|
677
|
+
```ruby
|
642
678
|
with(on { |arg| (arg % 2) == 0 } )
|
679
|
+
```
|
643
680
|
|
644
681
|
will match any even integer.
|
645
682
|
|
646
683
|
* If you wish to match a method call where a block is given, add
|
647
|
-
|
684
|
+
`Proc` as the last argument to `with`.
|
648
685
|
|
649
686
|
Example:
|
650
687
|
|
688
|
+
```ruby
|
651
689
|
m.should_receive(:foo).with(Integer,Proc).and_return(:got_block)
|
652
690
|
m.should_receive(:foo).with(Integer).and_return(:no_block)
|
691
|
+
```
|
653
692
|
|
654
693
|
will cause the mock to return the following:
|
655
694
|
|
695
|
+
```ruby
|
656
696
|
m.foo(1) { } => returns :got_block
|
657
697
|
m.foo(1) => returns :no_block
|
698
|
+
```
|
658
699
|
|
659
|
-
|
700
|
+
### Creating Partial Mocks
|
660
701
|
|
661
702
|
Sometimes it is useful to mock the behavior of one or two methods in
|
662
703
|
an existing object without changing the behavior of the rest of the
|
663
|
-
object. If you pass a real object to the
|
664
|
-
|
665
|
-
|
704
|
+
object. If you pass a real object to the `flexmock` method, it will
|
705
|
+
allow you to use that real object in your test and will just mock out
|
706
|
+
the one or two methods that you specify.
|
666
707
|
|
667
708
|
For example, suppose that a Dog object uses a Woofer object to bark.
|
668
709
|
The code for Dog looks like this (we will leave the code for Woofer to
|
669
710
|
your imagination):
|
670
711
|
|
712
|
+
```ruby
|
671
713
|
class Dog
|
672
714
|
def initialize
|
673
715
|
@woofer = Woofer.new
|
@@ -679,16 +721,18 @@ your imagination):
|
|
679
721
|
:happy
|
680
722
|
end
|
681
723
|
end
|
724
|
+
```
|
682
725
|
|
683
726
|
Now we want to test Dog, but using a real Woofer object in the test is
|
684
727
|
a real pain (why? ... well because Woofer plays a sound file of a dog
|
685
728
|
barking, and that's really annoying during testing).
|
686
729
|
|
687
730
|
So, how can we create a Dog object with mocked Woofer? All we need to
|
688
|
-
do is allow FlexMock to replace the
|
731
|
+
do is allow FlexMock to replace the `bark` method.
|
689
732
|
|
690
733
|
Here's the test code:
|
691
734
|
|
735
|
+
```ruby
|
692
736
|
class TestDogBarking < Test::Unit::TestCase
|
693
737
|
include FlexMock::TestCase
|
694
738
|
|
@@ -704,29 +748,31 @@ Here's the test code:
|
|
704
748
|
assert_equal :happy, @dog.wag # Normal Method
|
705
749
|
end
|
706
750
|
end
|
751
|
+
```
|
707
752
|
|
708
753
|
The nice thing about this technique is that after the test is over,
|
709
754
|
the mocked out methods are returned to their normal state. Outside the
|
710
755
|
test everything is back to normal.
|
711
756
|
|
712
|
-
<
|
713
|
-
called "stubs" and the
|
714
|
-
|
715
|
-
|
716
|
-
uses the
|
717
|
-
|
718
|
-
|
719
|
-
|
720
|
-
|
721
|
-
|
757
|
+
**NOTE:** <em>In previous versions of FlexMock, partial mocking was
|
758
|
+
called "stubs" and the `flexstub` method was used to create the
|
759
|
+
partial mocks. Although partial mocks were often used as stubs, the
|
760
|
+
terminology was not quite correct. The current version of FlexMock
|
761
|
+
uses the `flexmock` method to create both regular stubs and partial
|
762
|
+
stubs. A version of the `flexstub` method is included for backwards
|
763
|
+
compatibility. See Martin Fowler's article
|
764
|
+
[_Mocks Aren't Stubs_](http://www.martinfowler.com/articles/mocksArentStubs.html
|
765
|
+
"Mocks Aren't Stubs") for a better understanding of the difference
|
766
|
+
between mocks and stubs.</em>
|
722
767
|
|
723
|
-
This partial mocking technique was inspired by the
|
724
|
-
|
768
|
+
This partial mocking technique was inspired by the `Stuba` library in
|
769
|
+
the `Mocha` project.
|
725
770
|
|
726
|
-
|
771
|
+
### Spies
|
727
772
|
|
728
773
|
FlexMock supports spy-like mocks as well as the traditional mocks.
|
729
774
|
|
775
|
+
```ruby
|
730
776
|
# In Test::Unit / MiniTest
|
731
777
|
class TestDogBarking < Test::Unit::TestCase
|
732
778
|
def test_dog
|
@@ -744,11 +790,13 @@ FlexMock supports spy-like mocks as well as the traditional mocks.
|
|
744
790
|
dog.should have_received(:bark).with("loud")
|
745
791
|
end
|
746
792
|
end
|
793
|
+
```
|
747
794
|
|
748
795
|
Since spies are verified after the code under test is run, they fit
|
749
796
|
very nicely with the Given/When/Then technique of specification. Here
|
750
797
|
is the above RSpec example using the rspec-given gem:
|
751
798
|
|
799
|
+
```ruby
|
752
800
|
require 'rspec/given'
|
753
801
|
|
754
802
|
describe Dog do
|
@@ -759,51 +807,84 @@ is the above RSpec example using the rspec-given gem:
|
|
759
807
|
Then { dog.should have_received(:bark).with("loud") }
|
760
808
|
end
|
761
809
|
end
|
810
|
+
```
|
762
811
|
|
763
|
-
*NOTE:* You can only spy on methods that are mocked or stubbed.
|
764
|
-
not a problem with regular mocks, but normal methods on partial
|
765
|
-
objects will not be recorded
|
812
|
+
*NOTE:* <em>You can only spy on methods that are mocked or stubbed.
|
813
|
+
That's not a problem with regular mocks, but normal methods on partial
|
814
|
+
objects will not be recorded.</em>
|
766
815
|
|
767
816
|
You can get around this limitation by stubbing the method in question
|
768
|
-
on the normal mock, and then specifying
|
769
|
-
|
770
|
-
|
817
|
+
on the normal mock, and then specifying `pass_thru`. Assuming `:bark`
|
818
|
+
is a normal method on a Dog object, then the following allows for
|
819
|
+
spying on `:bark`.
|
771
820
|
|
821
|
+
```ruby
|
772
822
|
dog = Dog.new
|
773
823
|
flexmock(dog).should_receive(:bark).pass_thru
|
774
824
|
# ...
|
775
825
|
dog.should have_received(:bark)
|
826
|
+
```
|
776
827
|
|
777
|
-
|
828
|
+
#### Asserting Spy Methods are Called (Test::Unit / MiniTest)
|
778
829
|
|
779
830
|
FlexMock provied a custom assertion method for use with Test::Unit and
|
780
831
|
MiniTest for asserting that mocked methods are actually called.
|
781
832
|
|
782
833
|
* <b>assert_spy_called <em>mock</em>, <em>options_hash</em>, <em>method_name</em>, <em>args...</em></b>
|
783
834
|
|
784
|
-
This will assert that the method called
|
785
|
-
|
835
|
+
This will assert that the method called _method_name_ has been
|
836
|
+
called at least once on the given mock object. If arguments are
|
786
837
|
given, then the method must be called with actual argument that
|
787
838
|
match the given argument matchers.
|
788
839
|
|
789
840
|
All the argument matchers defined in the "Argument Validation"
|
790
|
-
section above are allowed in the
|
841
|
+
section above are allowed in the `assert_spy_called`
|
791
842
|
method.
|
792
843
|
|
793
|
-
The
|
794
|
-
|
844
|
+
The `options` hash is optional. If omitted, all options will have
|
845
|
+
their default values. See below for spy option definitions.
|
795
846
|
|
796
847
|
* <b>assert_spy_not_called <em>mock</em>, <em>options_hash</em>, <em>method_name</em>, <em>args...</em></b>
|
797
848
|
|
798
|
-
Same as
|
849
|
+
Same as `assert_spy_called`, except with the sense of the
|
799
850
|
test reversed.
|
800
851
|
|
852
|
+
*Spy Options*
|
853
|
+
|
854
|
+
* <b>times: <em>n</em></b>
|
855
|
+
|
856
|
+
Specify the number of times a matching method should have been
|
857
|
+
invoked. `nil` (or omitted) means any number of times.
|
858
|
+
|
859
|
+
* <b>with_block: <em>true/false/nil</em>
|
860
|
+
|
861
|
+
Is a block required on the invocation? `true` means the method must
|
862
|
+
be invoked with a block. `false` means the method must have been
|
863
|
+
invoked without a block. `nil` means that the presence of a block
|
864
|
+
does not matter. Default is `nil`.
|
865
|
+
|
866
|
+
* <b>and: [<em>proc1</em>, <em>proc2...</em>]</b>
|
867
|
+
|
868
|
+
Additional validations to be run on each matching method call. The
|
869
|
+
list of arguments for each call is passed to the procs. This allows
|
870
|
+
additional validations on supplied arguments. Default is no
|
871
|
+
additional validations.
|
872
|
+
|
873
|
+
* <b>on: <em>n</em>
|
874
|
+
|
875
|
+
Only apply the additional validations on the <em>n</em>'th
|
876
|
+
invocation of the matching method. Default is apply additional
|
877
|
+
validations to all invocations.
|
878
|
+
|
801
879
|
*Examples:*
|
802
880
|
|
881
|
+
```ruby
|
803
882
|
dog = flexmock(:on, Dog)
|
804
883
|
|
805
884
|
dog.wag(:tail)
|
806
885
|
dog.wag(:head)
|
886
|
+
dog.bark(5)
|
887
|
+
dog.bark(6)
|
807
888
|
|
808
889
|
assert_spy_called dog, :wag, :tail
|
809
890
|
assert_spy_called dog, :wag, :head
|
@@ -812,36 +893,61 @@ MiniTest for asserting that mocked methods are actually called.
|
|
812
893
|
assert_spy_not_called dog, :bark
|
813
894
|
assert_spy_not_called dog, {times: 3}, :wag
|
814
895
|
|
815
|
-
|
896
|
+
is_even = proc { |n| assert_equal 0, n%2 }
|
897
|
+
assert_spy_called dog, { and: is_even, on: 2 }, :bark, Integer
|
898
|
+
```
|
899
|
+
|
900
|
+
#### RSpec Matcher for Spying
|
816
901
|
|
817
902
|
FlexMock also provides an RSpec matcher that can be used to specify
|
818
903
|
spy behavior.
|
819
904
|
|
820
|
-
* <b>mock.should have_received(<em>method_name</em>)
|
905
|
+
* <b>mock.should have_received(<em>method_name</em>).<em>modifier1</em>.<em>modifier2</em>...</b>
|
821
906
|
|
822
|
-
Specifies that the method named
|
907
|
+
Specifies that the method named _method_name_ should have
|
823
908
|
been received by the mock object with the given arguments.
|
824
909
|
|
825
|
-
|
910
|
+
Just like `should_receive`, `have_received` will accept a number of
|
911
|
+
modifiers that modify its behavior.
|
826
912
|
|
827
|
-
|
828
|
-
arguments are considered. <em>args</em> can be any of the argument
|
829
|
-
matches mentioned in the "Argument Validation" section above. If
|
830
|
-
<code>with</code> is not given, then the arguments are not
|
831
|
-
considered when finding matching calls.
|
913
|
+
*Modifiers for `have_received`*
|
832
914
|
|
833
|
-
|
834
|
-
<code>n</code> calls for that method name on the mock. If the
|
835
|
-
<code>times</code> clause is not given, then there must be at least
|
836
|
-
one call matching the method name (and arguments if they are
|
837
|
-
considered).
|
915
|
+
* <b>with(<em>args</em>)
|
838
916
|
|
839
|
-
|
840
|
-
|
841
|
-
|
917
|
+
If a `with` modifier is given, only messages with matching arguments
|
918
|
+
are considered. _args_ can be any of the argument matches mentioned
|
919
|
+
in the "Argument Validation" section above. If `with` is not given,
|
920
|
+
then the arguments are not considered when finding matching calls.
|
921
|
+
|
922
|
+
* <b>times(<em>n</em>)</b>
|
923
|
+
|
924
|
+
If a `times` modifier is given, then there must be exactly `n` calls
|
925
|
+
for that method name on the mock. If the `times` clause is not
|
926
|
+
given, then there must be at least one call matching the method name
|
927
|
+
(and arguments if they are considered).
|
928
|
+
|
929
|
+
* `never` is an alias for `times(0)`,
|
930
|
+
* `once` is an alias for `times(1)`, and
|
931
|
+
* `twice` is an alias for `times(2)`.
|
932
|
+
|
933
|
+
* <b>and { |args| <em>code</em> }</b>
|
934
|
+
|
935
|
+
If an `and` modifier is given, then the supplied block will be run as
|
936
|
+
additional validations on any matching call. Arguments to the
|
937
|
+
matching call will be supplied to the block. If multiple `and`
|
938
|
+
modifiers are given, all the blocks will be run. The additional
|
939
|
+
validations are run on all the matching calls unless an `on`
|
940
|
+
modifier is supplied.
|
941
|
+
|
942
|
+
* <b>on(<em>n</em>)</b>
|
943
|
+
|
944
|
+
If an `on` modifier is given, then the additional validations
|
945
|
+
supplied by `and` will only be run on the <em>n</em>'th invocation
|
946
|
+
of the matching method.
|
842
947
|
|
843
948
|
*Examples:*
|
844
949
|
|
950
|
+
```ruby
|
845
951
|
dog = flexmock(:on, Dog)
|
846
952
|
|
847
953
|
dog.wag(:tail)
|
@@ -854,22 +960,33 @@ spy behavior.
|
|
854
960
|
dog.should_not have_received(:bark)
|
855
961
|
dog.should_not have_received(:wag).times(3)
|
856
962
|
|
857
|
-
|
963
|
+
dog.bark(3)
|
964
|
+
dog.bark(6)
|
965
|
+
dog.should have_received(:bark).with(Integer).and { |arg|
|
966
|
+
(arg % 3).should == 0
|
967
|
+
}
|
968
|
+
dog.should have_received(:bark).with(Integer).and { |arg|
|
969
|
+
arg.should == 6
|
970
|
+
}.on(2)
|
971
|
+
|
972
|
+
```
|
858
973
|
|
859
|
-
|
860
|
-
a Dog object to avoid invoking the Woofer object. Perhaps a better
|
861
|
-
technique would be to mock the Woofer object directly. But Dog uses
|
862
|
-
Woofer explicitly so we cannot just pass in a mock object for Dog to
|
863
|
-
use.
|
974
|
+
### Mocking Class Object
|
864
975
|
|
865
|
-
|
866
|
-
|
867
|
-
|
976
|
+
In the previous example we mocked out the `bark` method of a Dog
|
977
|
+
object to avoid invoking the Woofer object. Perhaps a better technique
|
978
|
+
would be to mock the Woofer object directly. But Dog uses Woofer
|
979
|
+
explicitly so we cannot just pass in a mock object for Dog to use.
|
868
980
|
|
981
|
+
But wait, we can add mock behavior to any existing object, and classes
|
982
|
+
are objects in Ruby. So why don't we just mock out the Woofer class
|
983
|
+
object to return mocks for us.
|
984
|
+
|
985
|
+
```ruby
|
869
986
|
class TestDogBarking < Test::Unit::TestCase
|
870
987
|
include FlexMock::TestCase
|
871
988
|
|
872
|
-
# Setup the tests by mocking the
|
989
|
+
# Setup the tests by mocking the `new` method of
|
873
990
|
# Woofer and return a mock woofer.
|
874
991
|
def setup
|
875
992
|
flexmock(Woofer).should_receive(:new).
|
@@ -882,13 +999,15 @@ return mocks for us.
|
|
882
999
|
# returned by Woofer.new
|
883
1000
|
end
|
884
1001
|
end
|
1002
|
+
```
|
885
1003
|
|
886
|
-
|
1004
|
+
### Mocking Behavior in All Instances Created by a Class Object
|
887
1005
|
|
888
1006
|
Sometimes returning a single mock object is not enough. Occasionally you want
|
889
|
-
to mock
|
1007
|
+
to mock _every_ instance object created by a class. FlexMock makes this
|
890
1008
|
very easy.
|
891
1009
|
|
1010
|
+
```ruby
|
892
1011
|
class TestDogBarking < Test::Unit::TestCase
|
893
1012
|
include FlexMock::TestCase
|
894
1013
|
|
@@ -903,40 +1022,46 @@ very easy.
|
|
903
1022
|
assert_equal :grrrr, Dog.new.bark # are mocked.
|
904
1023
|
end
|
905
1024
|
end
|
1025
|
+
```
|
906
1026
|
|
907
|
-
Note that FlexMock adds the mock expectations after the original
|
908
|
-
|
909
|
-
|
910
|
-
|
1027
|
+
Note that FlexMock adds the mock expectations after the original `new`
|
1028
|
+
method has completed. If the original version of `new` yields the
|
1029
|
+
newly created instance to a block, that block will get an non-mocked
|
1030
|
+
version of the object.
|
911
1031
|
|
912
|
-
Note that
|
913
|
-
|
1032
|
+
Note that `new_instances` will accept a block if you wish to mock
|
1033
|
+
several methods at the same time. E.g.
|
914
1034
|
|
1035
|
+
```ruby
|
915
1036
|
flexmock(Woofer).new_instances do |m|
|
916
1037
|
m.should_receive(:woof).twice.and_return(:grrr)
|
917
1038
|
m.should_receive(:wag).at_least.once.and_return(:happy)
|
918
1039
|
end
|
1040
|
+
```
|
919
1041
|
|
920
|
-
|
1042
|
+
### Default Expectations on Mocks
|
921
1043
|
|
922
1044
|
Sometimes you want to setup a bunch of default expectations that are
|
923
1045
|
pretty much for a number of different tests. Then in the individual
|
924
1046
|
tests, you would like to override the default behavior on just that
|
925
1047
|
one method you are testing at the moment. You can do that by using
|
926
|
-
the
|
1048
|
+
the `by_default` modifier.
|
927
1049
|
|
928
1050
|
In your test setup you might have:
|
929
1051
|
|
1052
|
+
```ruby
|
930
1053
|
def setup
|
931
1054
|
@mock_dog = flexmock("Fido")
|
932
1055
|
@mock_dog.should_receive(:tail => :a_tail, :bark => "woof").by_default
|
933
1056
|
end
|
1057
|
+
```
|
934
1058
|
|
935
|
-
The behaviors for
|
936
|
-
perhaps you wish to verify that
|
937
|
-
given test.
|
938
|
-
override the default in the given test.
|
1059
|
+
The behaviors for `:tail` and `:bark` are good for most of the tests,
|
1060
|
+
but perhaps you wish to verify that `:bark` is called exactly once in
|
1061
|
+
a given test. Since :bark by default has no count expectations, you
|
1062
|
+
can override the default in the given test.
|
939
1063
|
|
1064
|
+
```ruby
|
940
1065
|
def test_something_where_bark_must_be_called_once
|
941
1066
|
@mock_dog.should_receive(:bark => "woof").once
|
942
1067
|
|
@@ -946,12 +1071,13 @@ override the default in the given test.
|
|
946
1071
|
# However, the default for :tail (which returns :a_tail)
|
947
1072
|
# is still active.
|
948
1073
|
end
|
1074
|
+
```
|
949
1075
|
|
950
1076
|
By setting defaults, your individual tests don't have to concern
|
951
1077
|
themselves with details of all the default setup. But the details of
|
952
1078
|
the overrides are right there in the body of the test.
|
953
1079
|
|
954
|
-
|
1080
|
+
### Mocking Law of Demeter Violations
|
955
1081
|
|
956
1082
|
The Law of Demeter says that you should only invoke methods on objects
|
957
1083
|
to which you have a direct connection, e.g. parameters, instance
|
@@ -959,12 +1085,15 @@ variables, and local variables. You can usually detect Law of Demeter
|
|
959
1085
|
violations by the excessive number of periods in an expression. For
|
960
1086
|
example:
|
961
1087
|
|
1088
|
+
```ruby
|
962
1089
|
car.chassis.axle.universal_joint.cog.turn
|
1090
|
+
```
|
963
1091
|
|
964
1092
|
The Law of Demeter has a very big impact on mocking. If you need to
|
965
1093
|
mock the "turn" method on "cog", you first have to mock chassis, axle,
|
966
1094
|
and universal_joint.
|
967
1095
|
|
1096
|
+
```ruby
|
968
1097
|
# Manually mocking a Law of Demeter violation
|
969
1098
|
cog = flexmock("cog")
|
970
1099
|
cog.should_receive(:turn).once.and_return(:ok)
|
@@ -972,6 +1101,7 @@ and universal_joint.
|
|
972
1101
|
axle = flexmock("axle", :universal_joint => joint)
|
973
1102
|
chassis = flexmock("chassis", :axle => axle)
|
974
1103
|
car = flexmock("car", :chassis => chassis)
|
1104
|
+
```
|
975
1105
|
|
976
1106
|
Yuck!
|
977
1107
|
|
@@ -983,66 +1113,65 @@ allow you to easily mock Demeter method chains.
|
|
983
1113
|
|
984
1114
|
Here's an example of Demeter chain mocking:
|
985
1115
|
|
1116
|
+
```ruby
|
986
1117
|
# Demeter chain mocking using the short form.
|
987
1118
|
car = flexmock("car")
|
988
1119
|
car.should_receive( "chassis.axle.universal_joint.cog.turn" => :ok).once
|
1120
|
+
```
|
989
1121
|
|
990
1122
|
You can also use the long form:
|
991
1123
|
|
1124
|
+
```ruby
|
992
1125
|
# Demeter chain mocking using the long form.
|
993
1126
|
car = flexmock("car")
|
994
1127
|
car.should_receive("chassis.axle.universal_joint.cog.turn").once.
|
995
1128
|
and_return(:ok)
|
1129
|
+
```
|
996
1130
|
|
997
|
-
That's it.
|
1131
|
+
That's it. Anywhere FlexMock accepts a method name for mocking, you
|
998
1132
|
can use a demeter chain and FlexMock will attempt to do the right
|
999
1133
|
thing.
|
1000
1134
|
|
1001
1135
|
But beware, there are a few limitations.
|
1002
1136
|
|
1003
1137
|
The all the methods in the chain, except for the last one, will mocked
|
1004
|
-
to return a mock object.
|
1138
|
+
to return a mock object. That mock object, in turn, will be mocked so
|
1005
1139
|
as to respond to the next method in the chain, returning the following
|
1006
|
-
mock.
|
1140
|
+
mock. And so on. If you try to manually mock out any of the chained
|
1007
1141
|
methods, you could easily interfer with the mocking specified by the
|
1008
|
-
Demeter chain.
|
1142
|
+
Demeter chain. FlexMock will attempt to catch problems when it can,
|
1009
1143
|
but there are certainly scenarios where it cannot detect the problem
|
1010
1144
|
beforehand.
|
1011
1145
|
|
1012
|
-
|
1146
|
+
## Examples
|
1013
1147
|
|
1014
1148
|
Refer to the following documents for examples of using FlexMock:
|
1015
1149
|
|
1016
|
-
*
|
1017
|
-
*
|
1018
|
-
|
1019
|
-
*NOTE:* <em>If the above links are not working, you probably need to
|
1020
|
-
read the documents from the {documentation
|
1021
|
-
site}[http://flexmock.rubyforge.org]</em>
|
1150
|
+
* [RSpec Examples](https://github.com/jimweirich/flexmock/blob/master/doc/examples/rspec_examples_spec.rb)
|
1151
|
+
* [Test::Unit / MiniTest Examples](https://github.com/jimweirich/flexmock/blob/master/doc/examples/test_unit_examples_test.rb)
|
1022
1152
|
|
1023
|
-
|
1153
|
+
## License
|
1024
1154
|
|
1025
|
-
Copyright 2003-
|
1155
|
+
Copyright 2003-2013 by Jim Weirich (jim.weirich@gmail.com).
|
1026
1156
|
All rights reserved.
|
1027
1157
|
|
1028
1158
|
Permission is granted for use, copying, modification, distribution,
|
1029
1159
|
and distribution of modified versions of this work as long as the
|
1030
1160
|
above copyright notice is included.
|
1031
1161
|
|
1032
|
-
|
1162
|
+
# Other stuff
|
1033
1163
|
|
1034
|
-
Author
|
1035
|
-
Requires
|
1164
|
+
* **Author** -- Jim Weirich <jim.weirich@gmail.com>
|
1165
|
+
* **Requires** -- Ruby 1.9.2 or later (also works with Ruby 1.8.7)
|
1036
1166
|
|
1037
|
-
|
1167
|
+
## See Also
|
1038
1168
|
|
1039
1169
|
If you like the spy capability of FlexMock, you should check out the
|
1040
|
-
rspec-given gem
|
1170
|
+
[rspec-given gem](http://rubygems.org/gems/rspec-given) that allows you
|
1041
1171
|
to use Given/When/Then statements in you specifications.
|
1042
1172
|
|
1043
|
-
|
1173
|
+
## Warranty
|
1044
1174
|
|
1045
|
-
This software is provided "as is" and without any express or
|
1046
|
-
|
1047
|
-
|
1048
|
-
purpose.
|
1175
|
+
This software is provided "as is" and without any express or implied
|
1176
|
+
warranties, including, without limitation, the implied warranties of
|
1177
|
+
merchantibility and fitness for a particular purpose.
|