flexmock 0.1.3 → 0.1.4
Sign up to get free protection for your applications and to get access to all the features.
- 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
|