mockery 0.4.1
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/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
|