mockery 0.4.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +106 -0
- data/lib/mockery/call.rb +40 -0
- data/lib/mockery/controller.rb +75 -0
- data/lib/mockery/mock.rb +158 -0
- data/lib/mockery/mock_class_factory.rb +54 -0
- data/lib/mockery/record_control.rb +54 -0
- data/lib/mockery/recorder.rb +48 -0
- data/tests/acc/acc_tests.rb +18 -0
- data/tests/acc/mockery/mockery_test.rb +105 -0
- data/tests/unit/mockery/call_test.rb +92 -0
- data/tests/unit/mockery/controller_test.rb +207 -0
- data/tests/unit/mockery/mock_class_factory_test.rb +207 -0
- data/tests/unit/mockery/mock_test.rb +247 -0
- data/tests/unit/mockery/record_control_test.rb +163 -0
- data/tests/unit/mockery/recorder_test.rb +67 -0
- data/tests/unit/unit_tests.rb +29 -0
- metadata +57 -0
@@ -0,0 +1,207 @@
|
|
1
|
+
|
2
|
+
#
|
3
|
+
# Name: MockFactoryTest (tests/unit/mockery/mock_factory_test.rb)
|
4
|
+
#
|
5
|
+
# Description:
|
6
|
+
#
|
7
|
+
# Unit tests for the Mockery::MockFactory object
|
8
|
+
#
|
9
|
+
#
|
10
|
+
# Copyright 2005 Gary Shea
|
11
|
+
#
|
12
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
13
|
+
# you may not use this file except in compliance with the License.
|
14
|
+
# You may obtain a copy of the License at
|
15
|
+
#
|
16
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
17
|
+
#
|
18
|
+
# Unless required by applicable law or agreed to in writing, software
|
19
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
20
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
21
|
+
# See the License for the specific language governing permissions and
|
22
|
+
# limitations under the License.
|
23
|
+
#
|
24
|
+
|
25
|
+
require 'test/unit'
|
26
|
+
|
27
|
+
require 'mockery/mock_class_factory'
|
28
|
+
|
29
|
+
class MockClassFactoryTest < Test::Unit::TestCase
|
30
|
+
|
31
|
+
def test_initialize
|
32
|
+
|
33
|
+
factory_class = Class.new(Mockery::MockClassFactory)
|
34
|
+
factory_class.class_eval {
|
35
|
+
attr_reader :klass,
|
36
|
+
:return_values
|
37
|
+
}
|
38
|
+
|
39
|
+
base_class = Class.new
|
40
|
+
factory = factory_class.new(base_class)
|
41
|
+
|
42
|
+
assert_equal(base_class, factory.klass.superclass)
|
43
|
+
|
44
|
+
assert_equal(Hash, factory.return_values.class)
|
45
|
+
|
46
|
+
assert_equal(true, factory.klass.method_defined?(:instance_history))
|
47
|
+
mock = factory.klass.new
|
48
|
+
assert_equal(nil, mock.instance_history)
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_add_method
|
53
|
+
|
54
|
+
# instruct the factory to mock a method.
|
55
|
+
# return values are pulled from an instance variable
|
56
|
+
|
57
|
+
factory_class = Class.new(Mockery::MockClassFactory)
|
58
|
+
factory_class.class_eval {
|
59
|
+
attr_accessor :klass
|
60
|
+
}
|
61
|
+
factory = factory_class.new(Class.new)
|
62
|
+
|
63
|
+
# this is the class that the user would be handing
|
64
|
+
# to the factory
|
65
|
+
base_class = Class.new
|
66
|
+
base_class.class_eval {
|
67
|
+
attr_accessor :instance_history
|
68
|
+
def blruk(num)
|
69
|
+
return 'boss hog'
|
70
|
+
end
|
71
|
+
}
|
72
|
+
|
73
|
+
# this is an adequate fake of the class built by the
|
74
|
+
# base_class method. henceforth the 'mock class'.
|
75
|
+
# this class overrides the one set by the constructor,
|
76
|
+
# so we don't have to worry about what the constructor
|
77
|
+
# is actually doing
|
78
|
+
klass = Class.new(base_class)
|
79
|
+
factory.klass = klass
|
80
|
+
|
81
|
+
# tell the factory to add an instrumented version of
|
82
|
+
# this method to the mock class. do it multiple times
|
83
|
+
# so we know it's (whatever that damn word is, grrr)
|
84
|
+
factory.add_method('blruk')
|
85
|
+
factory.add_method('blruk')
|
86
|
+
|
87
|
+
# create an instance of the mock class, find out what
|
88
|
+
# happens when the method is called.
|
89
|
+
|
90
|
+
mock_class = Class.new(klass)
|
91
|
+
mock_class.class_eval {
|
92
|
+
attr_writer :___blruk_rv
|
93
|
+
}
|
94
|
+
mock = mock_class.new
|
95
|
+
mock.instance_history = []
|
96
|
+
mock.___blruk_rv = [27, 'arf']
|
97
|
+
|
98
|
+
rv1 = mock.blruk('zzp', 47)
|
99
|
+
rv2 = mock.blruk('pwx', 83)
|
100
|
+
|
101
|
+
assert_equal(2, mock.instance_history.size)
|
102
|
+
|
103
|
+
# first call...
|
104
|
+
assert_equal(mock, mock.instance_history[0].caller)
|
105
|
+
assert_equal(:blruk, mock.instance_history[0].method_name)
|
106
|
+
assert_equal(['zzp', 47], mock.instance_history[0].args)
|
107
|
+
assert_equal(27, rv1)
|
108
|
+
|
109
|
+
# second call...
|
110
|
+
assert_equal(mock, mock.instance_history[1].caller)
|
111
|
+
assert_equal(:blruk, mock.instance_history[1].method_name)
|
112
|
+
assert_equal(['pwx', 83], mock.instance_history[1].args)
|
113
|
+
assert_equal('arf', rv2)
|
114
|
+
|
115
|
+
end
|
116
|
+
|
117
|
+
def test_create_initialize
|
118
|
+
|
119
|
+
# the initialize method sets up:
|
120
|
+
# 1) the instance variable where the
|
121
|
+
# call history is stored, and
|
122
|
+
# 2) the instance variables which hold
|
123
|
+
# values which are returned from
|
124
|
+
# the mocked methods.
|
125
|
+
|
126
|
+
factory_class = Class.new(Mockery::MockClassFactory)
|
127
|
+
factory_class.class_eval {
|
128
|
+
attr_accessor :klass,
|
129
|
+
:return_values
|
130
|
+
}
|
131
|
+
factory = factory_class.new(Class.new)
|
132
|
+
|
133
|
+
# this is the class that the user would be handing
|
134
|
+
# to the factory
|
135
|
+
base_class = Class.new
|
136
|
+
base_class.class_eval {
|
137
|
+
def blruk(num)
|
138
|
+
return 'boss hog'
|
139
|
+
end
|
140
|
+
}
|
141
|
+
|
142
|
+
# this is an adequate fake of the class built by the
|
143
|
+
# base_class method. henceforth the 'mock class'.
|
144
|
+
# this overrides the class given in the constructor
|
145
|
+
# above, so we're not testing the constructor.
|
146
|
+
klass = Class.new(base_class)
|
147
|
+
klass.class_eval {
|
148
|
+
attr_accessor :instance_history
|
149
|
+
}
|
150
|
+
factory.klass = klass
|
151
|
+
|
152
|
+
# set the return values for the #xxx method
|
153
|
+
rvs = {:xxx =>[27, 'dog']}
|
154
|
+
|
155
|
+
# create the initialize method
|
156
|
+
factory.create_initialize(rvs.keys)
|
157
|
+
|
158
|
+
# create an instance of the class
|
159
|
+
# so that the presence and contents of the
|
160
|
+
# return sequence can be tested
|
161
|
+
mock = klass.new
|
162
|
+
|
163
|
+
assert(mock.instance_variables.index('@__xxx_rv') != nil)
|
164
|
+
assert_equal(Array, mock.instance_history.class)
|
165
|
+
end
|
166
|
+
|
167
|
+
def test_create_instance
|
168
|
+
|
169
|
+
# use #new to create the instance and then
|
170
|
+
# set the return values for each method.
|
171
|
+
|
172
|
+
factory_class = Class.new(Mockery::MockClassFactory)
|
173
|
+
factory_class.class_eval {
|
174
|
+
attr_accessor :klass
|
175
|
+
}
|
176
|
+
factory = factory_class.new(Class.new)
|
177
|
+
|
178
|
+
rvs = {:xxx => ['arf', 94]}
|
179
|
+
|
180
|
+
# this is the class that the user would be handing
|
181
|
+
# to the factory
|
182
|
+
base_class = Class.new
|
183
|
+
base_class.class_eval {
|
184
|
+
attr_accessor :instance_history
|
185
|
+
attr_reader :___xxx_rv
|
186
|
+
def blruk(num)
|
187
|
+
return 'boss hog'
|
188
|
+
end
|
189
|
+
}
|
190
|
+
|
191
|
+
# this is an adequate fake of the class built by the
|
192
|
+
# base_class method. henceforth the 'mock class'.
|
193
|
+
# it overrides the class given in the constructor
|
194
|
+
# above, so we're not testing the constructor.
|
195
|
+
klass = Class.new(base_class)
|
196
|
+
factory.klass = klass
|
197
|
+
|
198
|
+
instance = factory.create_instance(rvs)
|
199
|
+
|
200
|
+
assert_equal(factory.klass, instance.class)
|
201
|
+
|
202
|
+
# the instance must have been set up with the correct values
|
203
|
+
|
204
|
+
assert_equal(['arf', 94], instance.___xxx_rv)
|
205
|
+
end
|
206
|
+
|
207
|
+
end
|
@@ -0,0 +1,247 @@
|
|
1
|
+
|
2
|
+
#
|
3
|
+
# Name: MockTest (tests/unit/mockery/mock_test.rb)
|
4
|
+
#
|
5
|
+
# Description:
|
6
|
+
#
|
7
|
+
# Unit tests for the Mockery::Mock object, which holds
|
8
|
+
# information used to construct a single mock object
|
9
|
+
#
|
10
|
+
#
|
11
|
+
# Copyright 2005 Gary Shea
|
12
|
+
#
|
13
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
14
|
+
# you may not use this file except in compliance with the License.
|
15
|
+
# You may obtain a copy of the License at
|
16
|
+
#
|
17
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
18
|
+
#
|
19
|
+
# Unless required by applicable law or agreed to in writing, software
|
20
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
21
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
22
|
+
# See the License for the specific language governing permissions and
|
23
|
+
# limitations under the License.
|
24
|
+
#
|
25
|
+
|
26
|
+
require 'test/unit'
|
27
|
+
|
28
|
+
require 'mockery/mock'
|
29
|
+
|
30
|
+
class MockTest < Test::Unit::TestCase
|
31
|
+
|
32
|
+
def test_initialize
|
33
|
+
|
34
|
+
# a new instance is initialized with a class object.
|
35
|
+
# a new mock class factory and recorder should be created
|
36
|
+
# by the initializer.
|
37
|
+
|
38
|
+
mock_class = Class.new(Mockery::Mock)
|
39
|
+
mock_class.class_eval {
|
40
|
+
attr_reader :class_factory,
|
41
|
+
:klass,
|
42
|
+
:recorder,
|
43
|
+
:return_values
|
44
|
+
}
|
45
|
+
|
46
|
+
klass = Class.new
|
47
|
+
|
48
|
+
mock = mock_class.new(klass)
|
49
|
+
|
50
|
+
assert_equal(klass, mock.klass)
|
51
|
+
assert_equal(Mockery::Recorder, mock.recorder.class)
|
52
|
+
assert_equal(Mockery::MockClassFactory, mock.class_factory.class)
|
53
|
+
assert_equal(nil, mock.return_values)
|
54
|
+
|
55
|
+
recorder = mock.recorder
|
56
|
+
def recorder.klass
|
57
|
+
return @klass
|
58
|
+
end
|
59
|
+
assert_equal(klass, recorder.klass)
|
60
|
+
|
61
|
+
factory = mock.class_factory
|
62
|
+
def factory.klass
|
63
|
+
return @klass
|
64
|
+
end
|
65
|
+
assert_equal(klass, factory.klass.superclass)
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_mocked_object
|
69
|
+
|
70
|
+
# mocked_object returns an instance of an object
|
71
|
+
# which is derived from the object the user
|
72
|
+
# gave us, with each method used in #record
|
73
|
+
# over-ridden so that the arguments can be
|
74
|
+
# recorded and the proper value (if any) returned.
|
75
|
+
#
|
76
|
+
# really what it does is set up an empty
|
77
|
+
# return_values hash, call process_history() to
|
78
|
+
# populate the hash, call add_methods() to build
|
79
|
+
# the mocked methods in the mock class, calls
|
80
|
+
# create_initialize to build the initialize() method
|
81
|
+
# in the mock class, and finally returns an instance
|
82
|
+
# of the mocked class constructed by the class_factory.
|
83
|
+
|
84
|
+
|
85
|
+
# can't tell if the return_values hash
|
86
|
+
# was changed unless we have a mock
|
87
|
+
# to look at it with.
|
88
|
+
|
89
|
+
klass = Class.new
|
90
|
+
|
91
|
+
mock_class = Class.new(Mockery::Mock)
|
92
|
+
mock_class.class_eval {
|
93
|
+
attr_reader :am_called,
|
94
|
+
:instance,
|
95
|
+
:ph_called,
|
96
|
+
:return_values
|
97
|
+
attr_writer :class_factory
|
98
|
+
def process_history
|
99
|
+
@ph_called = true
|
100
|
+
end
|
101
|
+
def add_methods
|
102
|
+
@am_called = true
|
103
|
+
end
|
104
|
+
}
|
105
|
+
mock = mock_class.new(klass)
|
106
|
+
|
107
|
+
# can't tell if the correct methods have
|
108
|
+
# been called on the factory without a mock
|
109
|
+
factory_class = Class.new
|
110
|
+
factory_class.class_eval {
|
111
|
+
attr_reader :names,
|
112
|
+
:rvs
|
113
|
+
attr_writer :ret_instance
|
114
|
+
def create_initialize(names)
|
115
|
+
@names = names
|
116
|
+
end
|
117
|
+
def create_instance(rvs)
|
118
|
+
@rvs = rvs
|
119
|
+
return @ret_instance
|
120
|
+
end
|
121
|
+
}
|
122
|
+
factory = factory_class.new
|
123
|
+
|
124
|
+
ret_obj = Object.new
|
125
|
+
factory.ret_instance = ret_obj
|
126
|
+
|
127
|
+
mock.class_factory = factory
|
128
|
+
|
129
|
+
obj = mock.mocked_object
|
130
|
+
assert_equal(true, mock.ph_called)
|
131
|
+
assert_equal(true, mock.am_called)
|
132
|
+
assert_equal(mock.return_values.keys, factory.names)
|
133
|
+
assert_equal(mock.return_values, factory.rvs)
|
134
|
+
assert_equal(ret_obj, obj)
|
135
|
+
|
136
|
+
# we will be needing the instance value in
|
137
|
+
# validate:
|
138
|
+
|
139
|
+
assert_equal(ret_obj, mock.instance)
|
140
|
+
|
141
|
+
return_values = mock.return_values
|
142
|
+
|
143
|
+
end
|
144
|
+
|
145
|
+
def test_process_history
|
146
|
+
|
147
|
+
# process_history steps through the history
|
148
|
+
# held by the recorder, building the return_values
|
149
|
+
# hash. every method used in the recorder is
|
150
|
+
# a key in the return_values hash. each call
|
151
|
+
# to the method is given either a 'nil' value
|
152
|
+
# or the value in call.return_value.
|
153
|
+
|
154
|
+
# will need a mock recorder, as that is where
|
155
|
+
# history comes from
|
156
|
+
|
157
|
+
rec_class = Class.new(Mockery::Recorder)
|
158
|
+
rec_class.class_eval {
|
159
|
+
attr_writer :history
|
160
|
+
}
|
161
|
+
rec = rec_class.new
|
162
|
+
|
163
|
+
# the mock recorder needs some history, so
|
164
|
+
# build a couple Call objects
|
165
|
+
|
166
|
+
call = Mockery::Call.new
|
167
|
+
call.method_name = :blork
|
168
|
+
call.args = ['a', 1]
|
169
|
+
call.caller = Object.new
|
170
|
+
call.return_value = 23
|
171
|
+
rec.history << call
|
172
|
+
|
173
|
+
call = Mockery::Call.new
|
174
|
+
call.method_name = :xnurg
|
175
|
+
call.return_value = 'igg'
|
176
|
+
rec.history << call
|
177
|
+
|
178
|
+
call = Mockery::Call.new
|
179
|
+
call.method_name = :xnurg
|
180
|
+
call.return_value = 'ogg'
|
181
|
+
rec.history << call
|
182
|
+
|
183
|
+
# will need a Mock object to load the recorder
|
184
|
+
# into and call process_history() on
|
185
|
+
|
186
|
+
mock_class = Class.new(Mockery::Mock)
|
187
|
+
mock_class.class_eval {
|
188
|
+
attr_accessor :recorder,
|
189
|
+
:return_values
|
190
|
+
}
|
191
|
+
mock = mock_class.new(Class.new)
|
192
|
+
|
193
|
+
mock.recorder = rec
|
194
|
+
mock.return_values = Hash.new
|
195
|
+
|
196
|
+
mock.process_history
|
197
|
+
|
198
|
+
assert_equal(2, mock.return_values.size)
|
199
|
+
assert_equal([23], mock.return_values[:blork])
|
200
|
+
assert_equal(['igg', 'ogg'], mock.return_values[:xnurg])
|
201
|
+
end
|
202
|
+
|
203
|
+
def test_add_methods
|
204
|
+
|
205
|
+
# add_methods steps through the method names
|
206
|
+
# in @return_values, adding each one to
|
207
|
+
# the class being built up in the mock class
|
208
|
+
# factory.
|
209
|
+
|
210
|
+
# will need to mock the object factory so we
|
211
|
+
# aren't trying to add real methods.
|
212
|
+
|
213
|
+
factory_class = Class.new
|
214
|
+
factory_class.class_eval {
|
215
|
+
attr_reader :method_name
|
216
|
+
def initialize
|
217
|
+
@method_name = []
|
218
|
+
end
|
219
|
+
def add_method(method_name)
|
220
|
+
@method_name << method_name
|
221
|
+
end
|
222
|
+
}
|
223
|
+
factory = factory_class.new
|
224
|
+
|
225
|
+
# will need a Mock object to load the factory
|
226
|
+
# into and call add_methods() on
|
227
|
+
|
228
|
+
mock_class = Class.new(Mockery::Mock)
|
229
|
+
mock_class.class_eval {
|
230
|
+
attr_accessor :return_values
|
231
|
+
attr_writer :class_factory
|
232
|
+
}
|
233
|
+
mock = mock_class.new(Class.new)
|
234
|
+
mock.class_factory = factory
|
235
|
+
mock.return_values = {
|
236
|
+
:xxx => nil,
|
237
|
+
:yyy => nil,
|
238
|
+
}
|
239
|
+
|
240
|
+
mock.add_methods
|
241
|
+
|
242
|
+
assert_equal(2, factory.method_name.size)
|
243
|
+
assert(factory.method_name.index(:xxx) != nil)
|
244
|
+
|
245
|
+
end
|
246
|
+
|
247
|
+
end
|