flexmock 0.5.1 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +10 -1
- data/README +390 -209
- data/Rakefile +31 -10
- data/doc/GoogleExample.rdoc +275 -0
- data/doc/releases/flexmock-0.6.0.rdoc +136 -0
- data/lib/flexmock.rb +3 -1160
- data/lib/flexmock/argument_matchers.rb +57 -0
- data/lib/flexmock/argument_types.rb +42 -0
- data/lib/flexmock/base.rb +22 -0
- data/lib/flexmock/composite.rb +10 -0
- data/lib/flexmock/core.rb +206 -0
- data/lib/flexmock/core_class_methods.rb +92 -0
- data/lib/flexmock/default_framework_adapter.rb +31 -0
- data/lib/flexmock/expectation.rb +334 -0
- data/lib/flexmock/expectation_director.rb +59 -0
- data/lib/flexmock/mock_container.rb +159 -0
- data/lib/flexmock/noop.rb +13 -0
- data/lib/flexmock/partial_mock.rb +226 -0
- data/lib/flexmock/recorder.rb +71 -0
- data/lib/flexmock/rspec.rb +34 -0
- data/lib/flexmock/test_unit.rb +32 -0
- data/lib/flexmock/test_unit_integration.rb +53 -0
- data/lib/flexmock/validators.rb +77 -0
- data/test/rspec_integration/integration_spec.rb +36 -0
- data/test/test_container_methods.rb +119 -0
- data/test/test_default_framework_adapter.rb +39 -0
- data/test/test_example.rb +1 -1
- data/test/test_extended_should_receive.rb +63 -0
- data/test/test_mock.rb +1 -1
- data/test/test_naming.rb +1 -1
- data/test/{test_any_instance.rb → test_new_instances.rb} +15 -8
- data/test/{test_stubbing.rb → test_partial_mock.rb} +44 -44
- data/test/test_record_mode.rb +1 -1
- data/test/test_samples.rb +6 -8
- data/test/test_should_receive.rb +7 -3
- data/test/test_tu_integration.rb +1 -1
- data/test/test_unit_integration/test_auto_test_unit.rb +34 -0
- metadata +30 -5
- data/test/test_class_interception.rb +0 -140
@@ -0,0 +1,334 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
#---
|
4
|
+
# Copyright 2003, 2004, 2005, 2006, 2007 by Jim Weirich (jim@weirichhouse.org).
|
5
|
+
# All rights reserved.
|
6
|
+
|
7
|
+
# Permission is granted for use, copying, modification, distribution,
|
8
|
+
# and distribution of modified versions of this work as long as the
|
9
|
+
# above copyright notice is included.
|
10
|
+
#+++
|
11
|
+
|
12
|
+
require 'flexmock/noop'
|
13
|
+
|
14
|
+
class FlexMock
|
15
|
+
|
16
|
+
####################################################################
|
17
|
+
# An Expectation is returned from each +should_receive+ message sent
|
18
|
+
# to mock object. Each expectation records how a message matching
|
19
|
+
# the message name (argument to +should_receive+) and the argument
|
20
|
+
# list (given by +with+) should behave. Mock expectations can be
|
21
|
+
# recorded by chaining the declaration methods defined in this
|
22
|
+
# class.
|
23
|
+
#
|
24
|
+
# For example:
|
25
|
+
#
|
26
|
+
# mock.should_receive(:meth).with(args).and_returns(result)
|
27
|
+
#
|
28
|
+
class Expectation
|
29
|
+
|
30
|
+
attr_reader :expected_args, :order_number
|
31
|
+
attr_accessor :mock
|
32
|
+
|
33
|
+
# Create an expectation for a method named +sym+.
|
34
|
+
def initialize(mock, sym)
|
35
|
+
@mock = mock
|
36
|
+
@sym = sym
|
37
|
+
@expected_args = nil
|
38
|
+
@count_validators = []
|
39
|
+
@count_validator_class = ExactCountValidator
|
40
|
+
@actual_count = 0
|
41
|
+
@return_value = nil
|
42
|
+
@return_block = lambda { @return_value }
|
43
|
+
@order_number = nil
|
44
|
+
end
|
45
|
+
|
46
|
+
def to_s
|
47
|
+
FlexMock.format_args(@sym, @expected_args)
|
48
|
+
end
|
49
|
+
|
50
|
+
# Verify the current call with the given arguments matches the
|
51
|
+
# expectations recorded in this object.
|
52
|
+
def verify_call(*args)
|
53
|
+
validate_order
|
54
|
+
@actual_count += 1
|
55
|
+
@return_block.call(*args)
|
56
|
+
end
|
57
|
+
|
58
|
+
# Is this expectation eligible to be called again? It is eligible
|
59
|
+
# only if all of its count validators agree that it is eligible.
|
60
|
+
def eligible?
|
61
|
+
@count_validators.all? { |v| v.eligible?(@actual_count) }
|
62
|
+
end
|
63
|
+
|
64
|
+
# Validate that the order
|
65
|
+
def validate_order
|
66
|
+
return if @order_number.nil?
|
67
|
+
FlexMock.check("method #{to_s} called out of order " +
|
68
|
+
"(expected order #{@order_number}, was #{@mock.mock_current_order})") {
|
69
|
+
@order_number >= @mock.mock_current_order
|
70
|
+
}
|
71
|
+
@mock.mock_current_order = @order_number
|
72
|
+
end
|
73
|
+
private :validate_order
|
74
|
+
|
75
|
+
# Validate the correct number of calls have been made. Called by
|
76
|
+
# the teardown process.
|
77
|
+
def mock_verify
|
78
|
+
@count_validators.each do |v|
|
79
|
+
v.validate(@actual_count)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
# Does the argument list match this expectation's argument
|
84
|
+
# specification.
|
85
|
+
def match_args(args)
|
86
|
+
# TODO: Rethink this:
|
87
|
+
# return false if @expected_args.nil?
|
88
|
+
return true if @expected_args.nil?
|
89
|
+
return false if args.size != @expected_args.size
|
90
|
+
(0...args.size).all? { |i| match_arg(@expected_args[i], args[i]) }
|
91
|
+
end
|
92
|
+
|
93
|
+
# Does the expected argument match the corresponding actual value.
|
94
|
+
def match_arg(expected, actual)
|
95
|
+
expected === actual ||
|
96
|
+
expected == actual ||
|
97
|
+
( Regexp === expected && expected === actual.to_s )
|
98
|
+
end
|
99
|
+
|
100
|
+
# Declare that the method should expect the given argument list.
|
101
|
+
def with(*args)
|
102
|
+
@expected_args = args
|
103
|
+
self
|
104
|
+
end
|
105
|
+
|
106
|
+
# Declare that the method should be called with no arguments.
|
107
|
+
def with_no_args
|
108
|
+
with
|
109
|
+
end
|
110
|
+
|
111
|
+
# Declare that the method can be called with any number of
|
112
|
+
# arguments of any type.
|
113
|
+
def with_any_args
|
114
|
+
@expected_args = nil
|
115
|
+
self
|
116
|
+
end
|
117
|
+
|
118
|
+
# :call-seq:
|
119
|
+
# and_return(value)
|
120
|
+
# and_return(value, value, ...)
|
121
|
+
# and_return { |*args| code }
|
122
|
+
#
|
123
|
+
# Declare that the method returns a particular value (when the
|
124
|
+
# argument list is matched).
|
125
|
+
#
|
126
|
+
# * If a single value is given, it will be returned for all matching
|
127
|
+
# calls.
|
128
|
+
# * If multiple values are given, each value will be returned in turn for
|
129
|
+
# each successive call. If the number of matching calls is greater
|
130
|
+
# than the number of values, the last value will be returned for
|
131
|
+
# the extra matching calls.
|
132
|
+
# * If a block is given, it is evaluated on each call and its
|
133
|
+
# value is returned.
|
134
|
+
#
|
135
|
+
# For example:
|
136
|
+
#
|
137
|
+
# mock.should_receive(:f).returns(12) # returns 12
|
138
|
+
#
|
139
|
+
# mock.should_receive(:f).with(String). # returns an
|
140
|
+
# returns { |str| str.upcase } # upcased string
|
141
|
+
#
|
142
|
+
# +and_return+ is an alias for +returns+.
|
143
|
+
#
|
144
|
+
def and_return(*args, &block)
|
145
|
+
@return_block =
|
146
|
+
if block_given?
|
147
|
+
block
|
148
|
+
else
|
149
|
+
lambda { args.size == 1 ? args.first : args.shift }
|
150
|
+
end
|
151
|
+
self
|
152
|
+
end
|
153
|
+
alias :returns :and_return # :nodoc:
|
154
|
+
|
155
|
+
# Declare that the method may be called any number of times.
|
156
|
+
def zero_or_more_times
|
157
|
+
at_least.never
|
158
|
+
end
|
159
|
+
|
160
|
+
# Declare that the method is called +limit+ times with the
|
161
|
+
# declared argument list. This may be modified by the +at_least+
|
162
|
+
# and +at_most+ declarators.
|
163
|
+
def times(limit)
|
164
|
+
@count_validators << @count_validator_class.new(self, limit) unless limit.nil?
|
165
|
+
@count_validator_class = ExactCountValidator
|
166
|
+
self
|
167
|
+
end
|
168
|
+
|
169
|
+
# Declare that the method is never expected to be called with the
|
170
|
+
# given argument list. This may be modified by the +at_least+ and
|
171
|
+
# +at_most+ declarators.
|
172
|
+
def never
|
173
|
+
times(0)
|
174
|
+
end
|
175
|
+
|
176
|
+
# Declare that the method is expected to be called exactly once
|
177
|
+
# with the given argument list. This may be modified by the
|
178
|
+
# +at_least+ and +at_most+ declarators.
|
179
|
+
def once
|
180
|
+
times(1)
|
181
|
+
end
|
182
|
+
|
183
|
+
# Declare that the method is expected to be called exactly twice
|
184
|
+
# with the given argument list. This may be modified by the
|
185
|
+
# +at_least+ and +at_most+ declarators.
|
186
|
+
def twice
|
187
|
+
times(2)
|
188
|
+
end
|
189
|
+
|
190
|
+
# Modifies the next call count declarator (+times+, +never+,
|
191
|
+
# +once+ or +twice+) so that the declarator means the method is
|
192
|
+
# called at least that many times.
|
193
|
+
#
|
194
|
+
# E.g. method f must be called at least twice:
|
195
|
+
#
|
196
|
+
# mock.should_receive(:f).at_least.twice
|
197
|
+
#
|
198
|
+
def at_least
|
199
|
+
@count_validator_class = AtLeastCountValidator
|
200
|
+
self
|
201
|
+
end
|
202
|
+
|
203
|
+
# Modifies the next call count declarator (+times+, +never+,
|
204
|
+
# +once+ or +twice+) so that the declarator means the method is
|
205
|
+
# called at most that many times.
|
206
|
+
#
|
207
|
+
# E.g. method f must be called no more than twice
|
208
|
+
#
|
209
|
+
# mock.should_receive(:f).at_most.twice
|
210
|
+
#
|
211
|
+
def at_most
|
212
|
+
@count_validator_class = AtMostCountValidator
|
213
|
+
self
|
214
|
+
end
|
215
|
+
|
216
|
+
# Declare that the given method must be called in order. All
|
217
|
+
# ordered method calls must be received in the order specified by
|
218
|
+
# the ordering of the +should_receive+ messages. Receiving a
|
219
|
+
# methods out of the specified order will cause a test failure.
|
220
|
+
#
|
221
|
+
# If the user needs more fine control over ordering
|
222
|
+
# (e.g. specifying that a group of messages may be received in any
|
223
|
+
# order as long as they all come after another group of messages),
|
224
|
+
# a _group_ _name_ may be specified in the +ordered+ calls. All
|
225
|
+
# messages within the same group may be received in any order.
|
226
|
+
#
|
227
|
+
# For example, in the following, messages +flip+ and +flop+ may be
|
228
|
+
# received in any order (because they are in the same group), but
|
229
|
+
# must occur strictly after +start+ but before +end+. The message
|
230
|
+
# +any_time+ may be received at any time because it is not
|
231
|
+
# ordered.
|
232
|
+
#
|
233
|
+
# m = FlexMock.new
|
234
|
+
# m.should_receive(:any_time)
|
235
|
+
# m.should_receive(:start).ordered
|
236
|
+
# m.should_receive(:flip).ordered(:flip_flop_group)
|
237
|
+
# m.should_receive(:flop).ordered(:flip_flop_group)
|
238
|
+
# m.should_receive(:end).ordered
|
239
|
+
#
|
240
|
+
def ordered(group_name=nil)
|
241
|
+
if group_name.nil?
|
242
|
+
@order_number = @mock.mock_allocate_order
|
243
|
+
elsif (num = @mock.mock_groups[group_name])
|
244
|
+
@order_number = num
|
245
|
+
else
|
246
|
+
@order_number = @mock.mock_allocate_order
|
247
|
+
@mock.mock_groups[group_name] = @order_number
|
248
|
+
end
|
249
|
+
self
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
##########################################################################
|
254
|
+
# A composite expectation allows several expectations to be grouped into a
|
255
|
+
# single composite and then apply the same constraints to all expectations
|
256
|
+
# in the group.
|
257
|
+
class CompositeExpectation
|
258
|
+
|
259
|
+
# Initialize the composite expectation.
|
260
|
+
def initialize
|
261
|
+
@expectations = []
|
262
|
+
end
|
263
|
+
|
264
|
+
# Add an expectation to the composite.
|
265
|
+
def add(expectation)
|
266
|
+
@expectations << expectation
|
267
|
+
end
|
268
|
+
|
269
|
+
# Apply the constraint method to all expectations in the composite.
|
270
|
+
def method_missing(sym, *args, &block)
|
271
|
+
@expectations.each do |expectation|
|
272
|
+
expectation.send(sym, *args, &block)
|
273
|
+
end
|
274
|
+
self
|
275
|
+
end
|
276
|
+
|
277
|
+
# The following methods return a value, so we make an arbitrary choice
|
278
|
+
# and return the value for the first expectation in the composite.
|
279
|
+
|
280
|
+
# Return the order number of the first expectation in the list.
|
281
|
+
def order_number
|
282
|
+
@expectations.first.order_number
|
283
|
+
end
|
284
|
+
|
285
|
+
# Return the associated mock object.
|
286
|
+
def mock
|
287
|
+
@expectations.first.mock
|
288
|
+
end
|
289
|
+
|
290
|
+
# Start a new method expectation. The following constraints will be
|
291
|
+
# applied to the new expectation.
|
292
|
+
def should_receive(*args, &block)
|
293
|
+
@expectations.first.mock.should_receive(*args, &block)
|
294
|
+
end
|
295
|
+
|
296
|
+
# Return a string representations
|
297
|
+
def to_s
|
298
|
+
if @expectations.size > 1
|
299
|
+
"[" + @expectations.collect { |e| e.to_s }.join(', ') + "]"
|
300
|
+
else
|
301
|
+
@expectations.first.to_s
|
302
|
+
end
|
303
|
+
end
|
304
|
+
end
|
305
|
+
|
306
|
+
##########################################################################
|
307
|
+
# An expectation recorder records any expectations received and plays them
|
308
|
+
# back on demand. This is used to collect the expectations in the blockless
|
309
|
+
# version of the new_instances call.
|
310
|
+
#
|
311
|
+
class ExpectationRecorder
|
312
|
+
|
313
|
+
# Initialize the recorder.
|
314
|
+
def initialize
|
315
|
+
@expectations = []
|
316
|
+
end
|
317
|
+
|
318
|
+
# Save any incoming messages to be played back later.
|
319
|
+
def method_missing(sym, *args, &block)
|
320
|
+
@expectations << [sym, args, block]
|
321
|
+
self
|
322
|
+
end
|
323
|
+
|
324
|
+
# Apply the recorded messages to the given object in a chaining fashion
|
325
|
+
# (i.e. the result of the previous call is used as the target of the next
|
326
|
+
# call).
|
327
|
+
def apply(mock)
|
328
|
+
obj = mock
|
329
|
+
@expectations.each do |sym, args, block|
|
330
|
+
obj = obj.send(sym, *args, &block)
|
331
|
+
end
|
332
|
+
end
|
333
|
+
end
|
334
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
#---
|
4
|
+
# Copyright 2003, 2004, 2005, 2006, 2007 by Jim Weirich (jim@weirichhouse.org).
|
5
|
+
# All rights reserved.
|
6
|
+
|
7
|
+
# Permission is granted for use, copying, modification, distribution,
|
8
|
+
# and distribution of modified versions of this work as long as the
|
9
|
+
# above copyright notice is included.
|
10
|
+
#+++
|
11
|
+
|
12
|
+
require 'flexmock/noop'
|
13
|
+
|
14
|
+
class FlexMock
|
15
|
+
|
16
|
+
####################################################################
|
17
|
+
# The expectation director is responsible for routing calls to the
|
18
|
+
# correct expectations for a given argument list.
|
19
|
+
#
|
20
|
+
class ExpectationDirector
|
21
|
+
|
22
|
+
# Create an ExpectationDirector for a mock object.
|
23
|
+
def initialize(sym)
|
24
|
+
@sym = sym
|
25
|
+
@expectations = []
|
26
|
+
@expected_order = nil
|
27
|
+
end
|
28
|
+
|
29
|
+
# Invoke the expectations for a given set of arguments.
|
30
|
+
#
|
31
|
+
# First, look for an expectation that matches the arguements and
|
32
|
+
# is eligible to be called. Failing that, look for a expectation
|
33
|
+
# that matches the arguments (at this point it will be ineligible,
|
34
|
+
# but at least we will get a good failure message). Finally,
|
35
|
+
# check for expectations that don't have any argument matching
|
36
|
+
# criteria.
|
37
|
+
def call(*args)
|
38
|
+
exp = @expectations.find { |e| e.match_args(args) && e.eligible? } ||
|
39
|
+
@expectations.find { |e| e.match_args(args) }
|
40
|
+
FlexMock.check("no matching handler found for " +
|
41
|
+
FlexMock.format_args(@sym, args)) { ! exp.nil? }
|
42
|
+
exp.verify_call(*args)
|
43
|
+
end
|
44
|
+
|
45
|
+
# Append an expectation to this director.
|
46
|
+
def <<(expectation)
|
47
|
+
@expectations << expectation
|
48
|
+
end
|
49
|
+
|
50
|
+
# Do the post test verification for this directory. Check all the
|
51
|
+
# expectations.
|
52
|
+
def mock_verify
|
53
|
+
@expectations.each do |exp|
|
54
|
+
exp.mock_verify
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
@@ -0,0 +1,159 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
#---
|
4
|
+
# Copyright 2003, 2004, 2005, 2006, 2007 by Jim Weirich (jim@weirichhouse.org).
|
5
|
+
# All rights reserved.
|
6
|
+
|
7
|
+
# Permission is granted for use, copying, modification, distribution,
|
8
|
+
# and distribution of modified versions of this work as long as the
|
9
|
+
# above copyright notice is included.
|
10
|
+
#+++
|
11
|
+
|
12
|
+
require 'flexmock/noop'
|
13
|
+
|
14
|
+
class FlexMock
|
15
|
+
|
16
|
+
####################################################################
|
17
|
+
# Mock container methods
|
18
|
+
#
|
19
|
+
# Include this module in to get integration with FlexMock. When
|
20
|
+
# this module is included, mocks may be created with a simple call
|
21
|
+
# to the +flexmock+ method. Mocks created with via the method call
|
22
|
+
# will automatically be verified in the teardown of the test case.
|
23
|
+
#
|
24
|
+
module MockContainer
|
25
|
+
# Do the flexmock specific teardown stuff. If you need finer control,
|
26
|
+
# you can use either +flexmock_verify+ or +flexmock_close+.
|
27
|
+
def flexmock_teardown
|
28
|
+
flexmock_verify if passed?
|
29
|
+
ensure
|
30
|
+
flexmock_close
|
31
|
+
end
|
32
|
+
|
33
|
+
# Perform verification on all mocks in the container.
|
34
|
+
def flexmock_verify
|
35
|
+
@flexmock_created_mocks ||= []
|
36
|
+
@flexmock_created_mocks.each do |m|
|
37
|
+
m.mock_verify
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# Close all the mock objects in the container. Closing a mock object
|
42
|
+
# restores any original behavior that was displaced by the mock.
|
43
|
+
def flexmock_close
|
44
|
+
@flexmock_created_mocks ||= []
|
45
|
+
@flexmock_created_mocks.each do |m|
|
46
|
+
m.mock_teardown
|
47
|
+
end
|
48
|
+
@flexmock_created_mocks = []
|
49
|
+
end
|
50
|
+
|
51
|
+
# Create a mocking object in the FlexMock framework. The +flexmock+
|
52
|
+
# method has a number of options available, depending on just what
|
53
|
+
# kind of mocking object your require. Mocks created via +flexmock+
|
54
|
+
# will be automatically verify during the teardown phase of your
|
55
|
+
# test framework.
|
56
|
+
#
|
57
|
+
# :call-seq:
|
58
|
+
# flexmock() { |mock| ... }
|
59
|
+
# flexmock(name) { |mock| ... }
|
60
|
+
# flexmock(expect_hash) { |mock| ... }
|
61
|
+
# flexmock(name, expect_hash) { |mock| ... }
|
62
|
+
# flexmock(real_object) { |mock| ... }
|
63
|
+
# flexmock(real_object, name) { |mock| ... }
|
64
|
+
# flexmock(real_object, name, expect_hash) { |mock| ... }
|
65
|
+
# flexmock(:base, string, name, expect_hash) { |mock| ... }
|
66
|
+
#
|
67
|
+
# name ::
|
68
|
+
# Name of the mock object. If no name is given, "unknown" is used for
|
69
|
+
# full mocks and "flexmock(<em>real_object</em>)" is used for partial
|
70
|
+
# mocks.
|
71
|
+
#
|
72
|
+
# expect_hash ::
|
73
|
+
# Hash table of method names and values. Each method/value pair is
|
74
|
+
# used to setup a simple expectation so that if the mock object
|
75
|
+
# receives a message matching an entry in the table, it returns
|
76
|
+
# the associated value. No argument our call count constraints are
|
77
|
+
# added. Using an expect_hash is identical to calling:
|
78
|
+
#
|
79
|
+
# mock.should_receive(method_name).and_return(value)
|
80
|
+
#
|
81
|
+
# for each of the method/value pairs in the hash.
|
82
|
+
#
|
83
|
+
# real_object ::
|
84
|
+
# If a real object is given, then a partial mock is constructed
|
85
|
+
# using the real_object as a base. Partial mocks (formally referred
|
86
|
+
# to as stubs) behave as a mock object when an expectation is matched,
|
87
|
+
# and otherwise will behave like the original object. This is useful
|
88
|
+
# when you want to use a real object for testing, but need to mock out
|
89
|
+
# just one or two methods.
|
90
|
+
#
|
91
|
+
# :base ::
|
92
|
+
# Forces the following argument to be used as the base of a
|
93
|
+
# partial mock object. This explicit tag is only needed if you
|
94
|
+
# want to use a string or a symbol as the mock base (string and
|
95
|
+
# symbols would normally be interpretted as the mock name).
|
96
|
+
#
|
97
|
+
# &block ::
|
98
|
+
# If a block is given, then the mock object is passed to the block and
|
99
|
+
# expectations may be configured within the block.
|
100
|
+
#
|
101
|
+
def flexmock(*args)
|
102
|
+
name = nil
|
103
|
+
quick_defs = {}
|
104
|
+
stub_target = nil
|
105
|
+
while ! args.empty?
|
106
|
+
case args.first
|
107
|
+
when :base
|
108
|
+
args.shift
|
109
|
+
stub_target = args.shift
|
110
|
+
when String, Symbol
|
111
|
+
name = args.shift.to_s
|
112
|
+
when Hash
|
113
|
+
quick_defs = args.shift
|
114
|
+
else
|
115
|
+
stub_target = args.shift
|
116
|
+
end
|
117
|
+
end
|
118
|
+
if stub_target
|
119
|
+
mock = flexmock_make_stub(stub_target, name)
|
120
|
+
else
|
121
|
+
mock = FlexMock.new(name || "unknown")
|
122
|
+
end
|
123
|
+
flexmock_quick_define(mock, quick_defs)
|
124
|
+
yield(mock) if block_given?
|
125
|
+
flexmock_remember(mock)
|
126
|
+
mock
|
127
|
+
end
|
128
|
+
alias flexstub flexmock
|
129
|
+
|
130
|
+
private
|
131
|
+
|
132
|
+
# Create a PartialMock for the given object. Use +name+ as the name
|
133
|
+
# of the mock object.
|
134
|
+
def flexmock_make_stub(obj, name)
|
135
|
+
name ||= "flexmock(#{obj.class.to_s})"
|
136
|
+
obj.instance_eval {
|
137
|
+
@flexmock_proxy ||= PartialMock.new(obj, FlexMock.new(name))
|
138
|
+
}
|
139
|
+
obj.instance_variable_get("@flexmock_proxy")
|
140
|
+
end
|
141
|
+
|
142
|
+
# Create a set of mocked methods from a hash.
|
143
|
+
def flexmock_quick_define(mock, defs)
|
144
|
+
defs.each do |method, value|
|
145
|
+
mock.should_receive(method).and_return(value)
|
146
|
+
end
|
147
|
+
mock
|
148
|
+
end
|
149
|
+
|
150
|
+
# Remember the mock object / stub in the mock container.
|
151
|
+
def flexmock_remember(mocking_object)
|
152
|
+
@flexmock_created_mocks ||= []
|
153
|
+
@flexmock_created_mocks << mocking_object
|
154
|
+
mocking_object.mock_container = self
|
155
|
+
mocking_object
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
end
|