flexmock 0.1.3 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +5 -0
- data/README +7 -4
- data/Rakefile +1 -1
- data/lib/flexmock.rb +106 -57
- data/test/test_should_receive.rb +62 -2
- metadata +3 -3
data/CHANGELOG
CHANGED
data/README
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
FlexMock is a simple mock object for unit testing. The interface is
|
4
4
|
simple, but still provides a good bit of flexibility.
|
5
5
|
|
6
|
-
Version :: 0.1.
|
6
|
+
Version :: 0.1.4
|
7
7
|
|
8
8
|
= Links
|
9
9
|
|
@@ -143,9 +143,12 @@ values to figure out what value to return.
|
|
143
143
|
|
144
144
|
FlexMock('db').use |db|
|
145
145
|
db.should_receive(:startup).once.ordered
|
146
|
-
db.should_receive(:query).with("CPWR").and_return(12.3).
|
147
|
-
|
148
|
-
db.should_receive(:query).with(
|
146
|
+
db.should_receive(:query).with("CPWR").and_return(12.3).
|
147
|
+
once.ordered(:queries)
|
148
|
+
db.should_receive(:query).with("MSFT").and_return(10.0).
|
149
|
+
once.ordered(:queries)
|
150
|
+
db.should_receive(:query).with(/^....$/).and_return(3.3).
|
151
|
+
at_least.once.ordered(:queries)
|
149
152
|
db.should_receive(:finish).once.ordered
|
150
153
|
# test code here
|
151
154
|
end
|
data/Rakefile
CHANGED
data/lib/flexmock.rb
CHANGED
@@ -118,50 +118,54 @@ class FlexMock
|
|
118
118
|
result
|
119
119
|
end
|
120
120
|
|
121
|
-
|
122
|
-
|
123
|
-
# use method. The mocks will be passed to the block as arguments.
|
124
|
-
# If no names are given, then a single anonymous mock object will be
|
125
|
-
# created.
|
126
|
-
#
|
127
|
-
# At the end of the use block, each mock object will be verified to
|
128
|
-
# make sure the proper number of calls have been made.
|
129
|
-
#
|
130
|
-
# Usage:
|
131
|
-
#
|
132
|
-
# FlexMock.use("name") do |mock| # Creates a mock named "name"
|
133
|
-
# mock.should_receive(:meth).
|
134
|
-
# returns(0).once
|
135
|
-
# end # mock is verified here
|
136
|
-
#
|
137
|
-
def self.use(*names)
|
138
|
-
names = ["unknown"] if names.empty?
|
139
|
-
got_excecption = false
|
140
|
-
mocks = names.collect { |n| new(n) }
|
141
|
-
yield(*mocks)
|
142
|
-
rescue Exception => ex
|
143
|
-
got_exception = true
|
144
|
-
raise
|
145
|
-
ensure
|
146
|
-
mocks.each do |mock|
|
147
|
-
mock.mock_verify unless got_exception
|
148
|
-
end
|
149
|
-
end
|
121
|
+
class << self
|
122
|
+
include Test::Unit::Assertions
|
150
123
|
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
124
|
+
# Class method to make sure that verify is called at the end of a
|
125
|
+
# test. One mock object will be created for each name given to
|
126
|
+
# the use method. The mocks will be passed to the block as
|
127
|
+
# arguments. If no names are given, then a single anonymous mock
|
128
|
+
# object will be created.
|
129
|
+
#
|
130
|
+
# At the end of the use block, each mock object will be verified
|
131
|
+
# to make sure the proper number of calls have been made.
|
132
|
+
#
|
133
|
+
# Usage:
|
134
|
+
#
|
135
|
+
# FlexMock.use("name") do |mock| # Creates a mock named "name"
|
136
|
+
# mock.should_receive(:meth).
|
137
|
+
# returns(0).once
|
138
|
+
# end # mock is verified here
|
139
|
+
#
|
140
|
+
def use(*names)
|
141
|
+
names = ["unknown"] if names.empty?
|
142
|
+
got_excecption = false
|
143
|
+
mocks = names.collect { |n| new(n) }
|
144
|
+
yield(*mocks)
|
145
|
+
rescue Exception => ex
|
146
|
+
got_exception = true
|
147
|
+
raise
|
148
|
+
ensure
|
149
|
+
mocks.each do |mock|
|
150
|
+
mock.mock_verify unless got_exception
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
# Class method to format a method name and argument list as a nice
|
155
|
+
# looking string.
|
156
|
+
def format_args(sym, args)
|
157
|
+
if args
|
158
|
+
"#{sym}(#{args.collect { |a| a.inspect }.join(', ')})"
|
159
|
+
else
|
160
|
+
"#{sym}(*args)"
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
# Check will assert the block returns true. If it doesn't, an
|
165
|
+
# assertion failure is triggered with the given message.
|
166
|
+
def check(msg, &block)
|
167
|
+
assert_block(msg, &block)
|
159
168
|
end
|
160
|
-
end
|
161
|
-
|
162
|
-
# Class method to consistently form failure exceptions
|
163
|
-
def self.failure(msg)
|
164
|
-
fail Test::Unit::AssertionFailedError, msg
|
165
169
|
end
|
166
170
|
|
167
171
|
private
|
@@ -193,10 +197,8 @@ class FlexMock
|
|
193
197
|
def call(*args)
|
194
198
|
exp = @expectations.find { |e| e.match_args(args) } ||
|
195
199
|
@expectations.find { |e| e.expected_args.nil? }
|
196
|
-
|
197
|
-
|
198
|
-
FlexMock.format_args(@sym, args)
|
199
|
-
end
|
200
|
+
FlexMock.check("no matching handler found for " +
|
201
|
+
FlexMock.format_args(@sym, args)) { ! exp.nil? }
|
200
202
|
exp.verify_call(*args)
|
201
203
|
end
|
202
204
|
|
@@ -219,13 +221,58 @@ class FlexMock
|
|
219
221
|
end
|
220
222
|
end
|
221
223
|
|
224
|
+
####################################################################
|
225
|
+
# Match any object
|
226
|
+
class AnyMatcher
|
227
|
+
def ===(target)
|
228
|
+
true
|
229
|
+
end
|
230
|
+
def inspect
|
231
|
+
"ANY"
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
####################################################################
|
236
|
+
# Match only things that are equal.
|
237
|
+
class EqualMatcher
|
238
|
+
def initialize(obj)
|
239
|
+
@obj = obj
|
240
|
+
end
|
241
|
+
def ===(target)
|
242
|
+
@obj == target
|
243
|
+
end
|
244
|
+
def inspect
|
245
|
+
"==(#{@obj.inspect})"
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
249
|
+
ANY = AnyMatcher.new
|
250
|
+
|
251
|
+
####################################################################
|
252
|
+
# Include this module in your test class if you wish to use the +eq+
|
253
|
+
# and +any+ argument matching methods without a prefix. (Otherwise
|
254
|
+
# use <tt>FlexMock.any</tt> and <tt>FlexMock.eq(obj)</tt>.
|
255
|
+
#
|
256
|
+
module ArgumentTypes
|
257
|
+
# Return an argument matcher that matches any argument.
|
258
|
+
def any
|
259
|
+
ANY
|
260
|
+
end
|
261
|
+
|
262
|
+
# Return an argument matcher that only matches things equal to
|
263
|
+
# (==) the given object.
|
264
|
+
def eq(obj)
|
265
|
+
EqualMatcher.new(obj)
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
222
269
|
####################################################################
|
223
270
|
# Base class for all the count validators.
|
224
271
|
#
|
225
272
|
class CountValidator
|
226
273
|
include Test::Unit::Assertions
|
227
|
-
def initialize(
|
228
|
-
@
|
274
|
+
def initialize(expectation, limit)
|
275
|
+
@exp = expectation
|
229
276
|
@limit = limit
|
230
277
|
end
|
231
278
|
end
|
@@ -238,7 +285,7 @@ class FlexMock
|
|
238
285
|
# times.
|
239
286
|
def validate(n)
|
240
287
|
assert_equal @limit, n,
|
241
|
-
"method '#{@
|
288
|
+
"method '#{@exp}' called incorrect number of times"
|
242
289
|
end
|
243
290
|
end
|
244
291
|
|
@@ -250,7 +297,7 @@ class FlexMock
|
|
250
297
|
# times.
|
251
298
|
def validate(n)
|
252
299
|
assert n >= @limit,
|
253
|
-
"Method '#{@
|
300
|
+
"Method '#{@exp}' should be called at least #{@limit} times,\n" +
|
254
301
|
"only called #{n} times"
|
255
302
|
end
|
256
303
|
end
|
@@ -262,7 +309,7 @@ class FlexMock
|
|
262
309
|
# Validate the method expectation was called at least +n+ times.
|
263
310
|
def validate(n)
|
264
311
|
assert n <= @limit,
|
265
|
-
"Method '#{@
|
312
|
+
"Method '#{@exp}' should be called at most #{@limit} times,\n" +
|
266
313
|
"only called #{n} times"
|
267
314
|
end
|
268
315
|
end
|
@@ -312,10 +359,10 @@ class FlexMock
|
|
312
359
|
# Validate that the order
|
313
360
|
def validate_order
|
314
361
|
return if @order_number.nil?
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
362
|
+
FlexMock.check("method #{to_s} called out of order " +
|
363
|
+
"(expected order #{@order_number}, was #{@mock.mock_current_order})") {
|
364
|
+
@order_number >= @mock.mock_current_order
|
365
|
+
}
|
319
366
|
@mock.mock_current_order = @order_number
|
320
367
|
end
|
321
368
|
private :validate_order
|
@@ -388,7 +435,7 @@ class FlexMock
|
|
388
435
|
# declared argument list. This may be modified by the +at_least+
|
389
436
|
# and +at_most+ declarators.
|
390
437
|
def times(limit)
|
391
|
-
@count_validators << @count_validator_class.new(
|
438
|
+
@count_validators << @count_validator_class.new(self, limit) unless limit.nil?
|
392
439
|
@count_validator_class = ExactCountValidator
|
393
440
|
self
|
394
441
|
end
|
@@ -448,7 +495,7 @@ class FlexMock
|
|
448
495
|
# If the user needs more fine control over ordering
|
449
496
|
# (e.g. specifying that a group of messages may be received in any
|
450
497
|
# order as long as they all come after another group of messages),
|
451
|
-
# a _group_
|
498
|
+
# a _group_ _name_ may be specified in the +ordered+ calls. All
|
452
499
|
# messages within the same group may be recieved in any order.
|
453
500
|
#
|
454
501
|
# For example, in the following, messages +flip+ and +flop+ may be
|
@@ -476,4 +523,6 @@ class FlexMock
|
|
476
523
|
self
|
477
524
|
end
|
478
525
|
end
|
526
|
+
|
527
|
+
extend ArgumentTypes
|
479
528
|
end
|
data/test/test_should_receive.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
require 'test/unit'
|
4
4
|
require 'flexmock'
|
5
5
|
|
6
|
-
class
|
6
|
+
class TestFlexMockShoulds < Test::Unit::TestCase
|
7
7
|
|
8
8
|
def test_defaults
|
9
9
|
FlexMock.use do |m|
|
@@ -64,7 +64,7 @@ class TestFlexMock < Test::Unit::TestCase
|
|
64
64
|
end
|
65
65
|
end
|
66
66
|
|
67
|
-
def
|
67
|
+
def test_with_any_args
|
68
68
|
FlexMock.use do |m|
|
69
69
|
m.should_receive(:hi).with_any_args
|
70
70
|
m.hi
|
@@ -74,6 +74,40 @@ class TestFlexMock < Test::Unit::TestCase
|
|
74
74
|
end
|
75
75
|
end
|
76
76
|
|
77
|
+
def test_with_any_single_arg_matching
|
78
|
+
FlexMock.use('greeter') do |m|
|
79
|
+
m.should_receive(:hi).with(1,FlexMock.any).twice
|
80
|
+
m.hi(1,2)
|
81
|
+
m.hi(1, "this is a test")
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_with_any_single_arg_nonmatching
|
86
|
+
FlexMock.use('greeter') do |m|
|
87
|
+
m.should_receive(:hi).times(3)
|
88
|
+
m.should_receive(:hi).with(1,FlexMock.any).never
|
89
|
+
m.hi
|
90
|
+
m.hi(1)
|
91
|
+
m.hi(1, "hi", nil)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def test_with_equal_arg_matching
|
96
|
+
FlexMock.use('greeter') do |m|
|
97
|
+
m.should_receive(:hi).with(FlexMock.eq(Object)).once
|
98
|
+
m.hi(Object)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def test_with_equal_arg_nonmatching
|
103
|
+
FlexMock.use('greeter') do |m|
|
104
|
+
m.should_receive(:hi).with(FlexMock.eq(Object)).never
|
105
|
+
m.should_receive(:hi).never
|
106
|
+
m.should_receive(:hi).with(1).once
|
107
|
+
m.hi(1)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
77
111
|
def test_args_matching_with_regex
|
78
112
|
FlexMock.use do |m|
|
79
113
|
m.should_receive(:hi).with(/one/).returns(10)
|
@@ -113,6 +147,22 @@ class TestFlexMock < Test::Unit::TestCase
|
|
113
147
|
end
|
114
148
|
end
|
115
149
|
|
150
|
+
def test_arg_matching_precedence_when_best_first
|
151
|
+
FlexMock.use("greeter") do |m|
|
152
|
+
m.should_receive(:hi).with(1).once
|
153
|
+
m.should_receive(:hi).with(FlexMock.any).never
|
154
|
+
m.hi(1)
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
def test_arg_matching_precedence_when_best_last_but_still_matches_first
|
159
|
+
FlexMock.use("greeter") do |m|
|
160
|
+
m.should_receive(:hi).with(FlexMock.any).once
|
161
|
+
m.should_receive(:hi).with(1).never
|
162
|
+
m.hi(1)
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
116
166
|
def test_never_and_never_called
|
117
167
|
FlexMock.use do |m|
|
118
168
|
m.should_receive(:hi).with(1).never
|
@@ -438,3 +488,13 @@ class TestFlexMock < Test::Unit::TestCase
|
|
438
488
|
end
|
439
489
|
|
440
490
|
end
|
491
|
+
|
492
|
+
class TestFlexMockShouldsWithInclude < Test::Unit::TestCase
|
493
|
+
include FlexMock::ArgumentTypes
|
494
|
+
def test_include
|
495
|
+
FlexMock.use("x") do |m|
|
496
|
+
m.should_receive(:hi).with(any).once
|
497
|
+
m.hi(1)
|
498
|
+
end
|
499
|
+
end
|
500
|
+
end
|
metadata
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
|
-
rubygems_version: 0.8.
|
2
|
+
rubygems_version: 0.8.11.3
|
3
3
|
specification_version: 1
|
4
4
|
name: flexmock
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.1.
|
7
|
-
date: 2005-
|
6
|
+
version: 0.1.4
|
7
|
+
date: 2005-11-02 00:00:00 -05:00
|
8
8
|
summary: Simple and Flexible Mock Objects for Testing
|
9
9
|
require_paths:
|
10
10
|
- lib
|