rspec-mocks 2.0.0.a1
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/.document +5 -0
- data/.gitignore +6 -0
- data/License.txt +22 -0
- data/README.markdown +8 -0
- data/Rakefile +50 -0
- data/VERSION +1 -0
- data/VERSION.yml +5 -0
- data/lib/rspec/mocks.rb +201 -0
- data/lib/rspec/mocks/argument_expectation.rb +51 -0
- data/lib/rspec/mocks/argument_matchers.rb +233 -0
- data/lib/rspec/mocks/error_generator.rb +81 -0
- data/lib/rspec/mocks/errors.rb +10 -0
- data/lib/rspec/mocks/extensions.rb +1 -0
- data/lib/rspec/mocks/extensions/object.rb +3 -0
- data/lib/rspec/mocks/framework.rb +15 -0
- data/lib/rspec/mocks/message_expectation.rb +326 -0
- data/lib/rspec/mocks/methods.rb +63 -0
- data/lib/rspec/mocks/mock.rb +65 -0
- data/lib/rspec/mocks/order_group.rb +29 -0
- data/lib/rspec/mocks/proxy.rb +230 -0
- data/lib/rspec/mocks/space.rb +28 -0
- data/lib/rspec/mocks/spec_methods.rb +39 -0
- data/lib/spec/mocks.rb +1 -0
- data/spec/rspec/mocks/any_number_of_times_spec.rb +36 -0
- data/spec/rspec/mocks/argument_expectation_spec.rb +23 -0
- data/spec/rspec/mocks/at_least_spec.rb +97 -0
- data/spec/rspec/mocks/at_most_spec.rb +93 -0
- data/spec/rspec/mocks/bug_report_10260_spec.rb +8 -0
- data/spec/rspec/mocks/bug_report_10263_spec.rb +27 -0
- data/spec/rspec/mocks/bug_report_11545_spec.rb +32 -0
- data/spec/rspec/mocks/bug_report_15719_spec.rb +29 -0
- data/spec/rspec/mocks/bug_report_496_spec.rb +17 -0
- data/spec/rspec/mocks/bug_report_600_spec.rb +22 -0
- data/spec/rspec/mocks/bug_report_7611_spec.rb +19 -0
- data/spec/rspec/mocks/bug_report_7805_spec.rb +22 -0
- data/spec/rspec/mocks/bug_report_8165_spec.rb +31 -0
- data/spec/rspec/mocks/bug_report_8302_spec.rb +26 -0
- data/spec/rspec/mocks/bug_report_830_spec.rb +21 -0
- data/spec/rspec/mocks/failing_argument_matchers_spec.rb +95 -0
- data/spec/rspec/mocks/hash_including_matcher_spec.rb +90 -0
- data/spec/rspec/mocks/hash_not_including_matcher_spec.rb +67 -0
- data/spec/rspec/mocks/mock_ordering_spec.rb +94 -0
- data/spec/rspec/mocks/mock_space_spec.rb +54 -0
- data/spec/rspec/mocks/mock_spec.rb +583 -0
- data/spec/rspec/mocks/multiple_return_value_spec.rb +113 -0
- data/spec/rspec/mocks/nil_expectation_warning_spec.rb +63 -0
- data/spec/rspec/mocks/null_object_mock_spec.rb +54 -0
- data/spec/rspec/mocks/once_counts_spec.rb +53 -0
- data/spec/rspec/mocks/options_hash_spec.rb +35 -0
- data/spec/rspec/mocks/partial_mock_spec.rb +164 -0
- data/spec/rspec/mocks/partial_mock_using_mocks_directly_spec.rb +66 -0
- data/spec/rspec/mocks/passing_argument_matchers_spec.rb +145 -0
- data/spec/rspec/mocks/precise_counts_spec.rb +52 -0
- data/spec/rspec/mocks/record_messages_spec.rb +26 -0
- data/spec/rspec/mocks/stub_chain_spec.rb +34 -0
- data/spec/rspec/mocks/stub_implementation_spec.rb +31 -0
- data/spec/rspec/mocks/stub_spec.rb +198 -0
- data/spec/rspec/mocks/stubbed_message_expectations_spec.rb +26 -0
- data/spec/rspec/mocks/twice_counts_spec.rb +67 -0
- data/spec/spec_helper.rb +52 -0
- data/spec/support/macros.rb +29 -0
- metadata +172 -0
@@ -0,0 +1,81 @@
|
|
1
|
+
module Rspec
|
2
|
+
module Mocks
|
3
|
+
class ErrorGenerator
|
4
|
+
attr_writer :opts
|
5
|
+
|
6
|
+
def initialize(target, name)
|
7
|
+
@target = target
|
8
|
+
@name = name
|
9
|
+
end
|
10
|
+
|
11
|
+
def opts
|
12
|
+
@opts ||= {}
|
13
|
+
end
|
14
|
+
|
15
|
+
def raise_unexpected_message_error(sym, *args)
|
16
|
+
__raise "#{intro} received unexpected message :#{sym}#{arg_message(*args)}"
|
17
|
+
end
|
18
|
+
|
19
|
+
def raise_unexpected_message_args_error(expectation, *args)
|
20
|
+
expected_args = format_args(*expectation.expected_args)
|
21
|
+
actual_args = args.empty? ? "(no args)" : format_args(*args)
|
22
|
+
__raise "#{intro} expected #{expectation.sym.inspect} with #{expected_args} but received it with #{actual_args}"
|
23
|
+
end
|
24
|
+
|
25
|
+
def raise_expectation_error(sym, expected_received_count, actual_received_count, *args)
|
26
|
+
__raise "#{intro} expected :#{sym}#{arg_message(*args)} #{count_message(expected_received_count)}, but received it #{count_message(actual_received_count)}"
|
27
|
+
end
|
28
|
+
|
29
|
+
def raise_out_of_order_error(sym)
|
30
|
+
__raise "#{intro} received :#{sym} out of order"
|
31
|
+
end
|
32
|
+
|
33
|
+
def raise_block_failed_error(sym, detail)
|
34
|
+
__raise "#{intro} received :#{sym} but passed block failed with: #{detail}"
|
35
|
+
end
|
36
|
+
|
37
|
+
def raise_missing_block_error(args_to_yield)
|
38
|
+
__raise "#{intro} asked to yield |#{arg_list(*args_to_yield)}| but no block was passed"
|
39
|
+
end
|
40
|
+
|
41
|
+
def raise_wrong_arity_error(args_to_yield, arity)
|
42
|
+
__raise "#{intro} yielded |#{arg_list(*args_to_yield)}| to block with arity of #{arity}"
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def intro
|
48
|
+
@name ? "Mock '#{@name}'" : @target.class == Class ? "<#{@target.inspect} (class)>" : (@target.nil? ? "nil" : @target)
|
49
|
+
end
|
50
|
+
|
51
|
+
def __raise(message)
|
52
|
+
message = opts[:message] unless opts[:message].nil?
|
53
|
+
Kernel::raise(Rspec::Mocks::MockExpectationError, message)
|
54
|
+
end
|
55
|
+
|
56
|
+
def arg_message(*args)
|
57
|
+
" with " + format_args(*args)
|
58
|
+
end
|
59
|
+
|
60
|
+
def format_args(*args)
|
61
|
+
args.empty? ? "(no args)" : "(" + arg_list(*args) + ")"
|
62
|
+
end
|
63
|
+
|
64
|
+
def arg_list(*args)
|
65
|
+
args.collect {|arg| arg.respond_to?(:description) ? arg.description : arg.inspect}.join(", ")
|
66
|
+
end
|
67
|
+
|
68
|
+
def count_message(count)
|
69
|
+
return "at least #{pretty_print(count.abs)}" if count < 0
|
70
|
+
return pretty_print(count)
|
71
|
+
end
|
72
|
+
|
73
|
+
def pretty_print(count)
|
74
|
+
return "once" if count == 1
|
75
|
+
return "twice" if count == 2
|
76
|
+
return "#{count} times"
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'rspec/mocks/extensions/object'
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# Require everything except the global extensions of class and object. This
|
2
|
+
# supports wrapping rspec's mocking functionality without invading every
|
3
|
+
# object in the system.
|
4
|
+
|
5
|
+
require 'rspec/mocks/methods'
|
6
|
+
require 'rspec/mocks/argument_matchers'
|
7
|
+
require 'rspec/mocks/spec_methods'
|
8
|
+
require 'rspec/mocks/proxy'
|
9
|
+
require 'rspec/mocks/mock'
|
10
|
+
require 'rspec/mocks/argument_expectation'
|
11
|
+
require 'rspec/mocks/message_expectation'
|
12
|
+
require 'rspec/mocks/order_group'
|
13
|
+
require 'rspec/mocks/errors'
|
14
|
+
require 'rspec/mocks/error_generator'
|
15
|
+
require 'rspec/mocks/space'
|
@@ -0,0 +1,326 @@
|
|
1
|
+
module Rspec
|
2
|
+
module Mocks
|
3
|
+
|
4
|
+
class BaseExpectation
|
5
|
+
attr_reader :sym
|
6
|
+
attr_writer :expected_received_count, :method_block, :expected_from
|
7
|
+
protected :expected_received_count=, :method_block=, :expected_from=
|
8
|
+
attr_accessor :error_generator
|
9
|
+
protected :error_generator, :error_generator=
|
10
|
+
|
11
|
+
def initialize(error_generator, expectation_ordering, expected_from, sym, method_block, expected_received_count=1, opts={}, &implementation)
|
12
|
+
@error_generator = error_generator
|
13
|
+
@error_generator.opts = opts
|
14
|
+
@expected_from = expected_from
|
15
|
+
@sym = sym
|
16
|
+
@method_block = method_block
|
17
|
+
@return_block = nil
|
18
|
+
@actual_received_count = 0
|
19
|
+
@expected_received_count = expected_received_count
|
20
|
+
@args_expectation = ArgumentExpectation.new([ArgumentMatchers::AnyArgsMatcher.new])
|
21
|
+
@consecutive = false
|
22
|
+
@exception_to_raise = nil
|
23
|
+
@symbol_to_throw = nil
|
24
|
+
@order_group = expectation_ordering
|
25
|
+
@at_least = nil
|
26
|
+
@at_most = nil
|
27
|
+
@args_to_yield = []
|
28
|
+
@failed_fast = nil
|
29
|
+
@args_to_yield_were_cloned = false
|
30
|
+
@return_block = implementation
|
31
|
+
end
|
32
|
+
|
33
|
+
def build_child(expected_from, method_block, expected_received_count, opts={})
|
34
|
+
child = clone
|
35
|
+
child.expected_from = expected_from
|
36
|
+
child.method_block = method_block
|
37
|
+
child.expected_received_count = expected_received_count
|
38
|
+
child.clear_actual_received_count!
|
39
|
+
new_gen = error_generator.clone
|
40
|
+
new_gen.opts = opts
|
41
|
+
child.error_generator = new_gen
|
42
|
+
child.clone_args_to_yield @args_to_yield
|
43
|
+
child
|
44
|
+
end
|
45
|
+
|
46
|
+
def expected_args
|
47
|
+
@args_expectation.args
|
48
|
+
end
|
49
|
+
|
50
|
+
def and_return(*values, &return_block)
|
51
|
+
Kernel::raise AmbiguousReturnError unless @method_block.nil?
|
52
|
+
case values.size
|
53
|
+
when 0 then value = nil
|
54
|
+
when 1 then value = values[0]
|
55
|
+
else
|
56
|
+
value = values
|
57
|
+
@consecutive = true
|
58
|
+
@expected_received_count = values.size if !ignoring_args? &&
|
59
|
+
@expected_received_count < values.size
|
60
|
+
end
|
61
|
+
@return_block = block_given? ? return_block : lambda { value }
|
62
|
+
end
|
63
|
+
|
64
|
+
# :call-seq:
|
65
|
+
# and_raise()
|
66
|
+
# and_raise(Exception) #any exception class
|
67
|
+
# and_raise(exception) #any exception object
|
68
|
+
#
|
69
|
+
# == Warning
|
70
|
+
#
|
71
|
+
# When you pass an exception class, the MessageExpectation will
|
72
|
+
# raise an instance of it, creating it with +new+. If the exception
|
73
|
+
# class initializer requires any parameters, you must pass in an
|
74
|
+
# instance and not the class.
|
75
|
+
def and_raise(exception=Exception)
|
76
|
+
@exception_to_raise = exception
|
77
|
+
end
|
78
|
+
|
79
|
+
def and_throw(symbol)
|
80
|
+
@symbol_to_throw = symbol
|
81
|
+
end
|
82
|
+
|
83
|
+
def and_yield(*args)
|
84
|
+
if @args_to_yield_were_cloned
|
85
|
+
@args_to_yield.clear
|
86
|
+
@args_to_yield_were_cloned = false
|
87
|
+
end
|
88
|
+
|
89
|
+
@args_to_yield << args
|
90
|
+
self
|
91
|
+
end
|
92
|
+
|
93
|
+
def matches(sym, args)
|
94
|
+
@sym == sym and @args_expectation.args_match?(args)
|
95
|
+
end
|
96
|
+
|
97
|
+
def invoke(args, block)
|
98
|
+
if @expected_received_count == 0
|
99
|
+
@failed_fast = true
|
100
|
+
@actual_received_count += 1
|
101
|
+
@error_generator.raise_expectation_error @sym, @expected_received_count, @actual_received_count, *args
|
102
|
+
end
|
103
|
+
|
104
|
+
@order_group.handle_order_constraint self
|
105
|
+
|
106
|
+
begin
|
107
|
+
Kernel::raise @exception_to_raise unless @exception_to_raise.nil?
|
108
|
+
Kernel::throw @symbol_to_throw unless @symbol_to_throw.nil?
|
109
|
+
|
110
|
+
|
111
|
+
if !@method_block.nil?
|
112
|
+
default_return_val = invoke_method_block(args)
|
113
|
+
elsif @args_to_yield.size > 0
|
114
|
+
default_return_val = invoke_with_yield(block)
|
115
|
+
else
|
116
|
+
default_return_val = nil
|
117
|
+
end
|
118
|
+
|
119
|
+
if @consecutive
|
120
|
+
return invoke_consecutive_return_block(args, block)
|
121
|
+
elsif @return_block
|
122
|
+
return invoke_return_block(args, block)
|
123
|
+
else
|
124
|
+
return default_return_val
|
125
|
+
end
|
126
|
+
ensure
|
127
|
+
@actual_received_count += 1
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
def called_max_times?
|
132
|
+
@expected_received_count != :any && @expected_received_count > 0 &&
|
133
|
+
@actual_received_count >= @expected_received_count
|
134
|
+
end
|
135
|
+
|
136
|
+
protected
|
137
|
+
|
138
|
+
def invoke_method_block(args)
|
139
|
+
begin
|
140
|
+
@method_block.call(*args)
|
141
|
+
rescue => detail
|
142
|
+
@error_generator.raise_block_failed_error @sym, detail.message
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
def invoke_with_yield(block)
|
147
|
+
if block.nil?
|
148
|
+
@error_generator.raise_missing_block_error @args_to_yield
|
149
|
+
end
|
150
|
+
value = nil
|
151
|
+
@args_to_yield.each do |args_to_yield_this_time|
|
152
|
+
if block.arity > -1 && args_to_yield_this_time.length != block.arity
|
153
|
+
@error_generator.raise_wrong_arity_error args_to_yield_this_time, block.arity
|
154
|
+
end
|
155
|
+
value = block.call(*args_to_yield_this_time)
|
156
|
+
end
|
157
|
+
value
|
158
|
+
end
|
159
|
+
|
160
|
+
def invoke_consecutive_return_block(args, block)
|
161
|
+
value = invoke_return_block(args, block)
|
162
|
+
index = [@actual_received_count, value.size-1].min
|
163
|
+
value[index]
|
164
|
+
end
|
165
|
+
|
166
|
+
def invoke_return_block(args, block)
|
167
|
+
args << block unless block.nil?
|
168
|
+
# Ruby 1.9 - when we set @return_block to return values
|
169
|
+
# regardless of arguments, any arguments will result in
|
170
|
+
# a "wrong number of arguments" error
|
171
|
+
@return_block.arity == 0 ? @return_block.call : @return_block.call(*args)
|
172
|
+
end
|
173
|
+
|
174
|
+
def clone_args_to_yield(args)
|
175
|
+
@args_to_yield = args.clone
|
176
|
+
@args_to_yield_were_cloned = true
|
177
|
+
end
|
178
|
+
|
179
|
+
def failed_fast?
|
180
|
+
@failed_fast
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
class MessageExpectation < BaseExpectation
|
185
|
+
|
186
|
+
def matches_name_but_not_args(sym, args)
|
187
|
+
@sym == sym and not @args_expectation.args_match?(args)
|
188
|
+
end
|
189
|
+
|
190
|
+
def verify_messages_received
|
191
|
+
return if expected_messages_received? || failed_fast?
|
192
|
+
|
193
|
+
generate_error
|
194
|
+
rescue Rspec::Mocks::MockExpectationError => error
|
195
|
+
error.backtrace.insert(0, @expected_from)
|
196
|
+
Kernel::raise error
|
197
|
+
end
|
198
|
+
|
199
|
+
def expected_messages_received?
|
200
|
+
ignoring_args? || matches_exact_count? ||
|
201
|
+
matches_at_least_count? || matches_at_most_count?
|
202
|
+
end
|
203
|
+
|
204
|
+
def ignoring_args?
|
205
|
+
@expected_received_count == :any
|
206
|
+
end
|
207
|
+
|
208
|
+
def matches_at_least_count?
|
209
|
+
@at_least && @actual_received_count >= @expected_received_count
|
210
|
+
end
|
211
|
+
|
212
|
+
def matches_at_most_count?
|
213
|
+
@at_most && @actual_received_count <= @expected_received_count
|
214
|
+
end
|
215
|
+
|
216
|
+
def matches_exact_count?
|
217
|
+
@expected_received_count == @actual_received_count
|
218
|
+
end
|
219
|
+
|
220
|
+
def similar_messages
|
221
|
+
@similar_messages ||= []
|
222
|
+
end
|
223
|
+
|
224
|
+
def advise(args, block)
|
225
|
+
similar_messages << args
|
226
|
+
end
|
227
|
+
|
228
|
+
def generate_error
|
229
|
+
if similar_messages.empty?
|
230
|
+
@error_generator.raise_expectation_error(@sym, @expected_received_count, @actual_received_count, *@args_expectation.args)
|
231
|
+
else
|
232
|
+
@error_generator.raise_unexpected_message_args_error(self, *@similar_messages)
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
def with(*args, &block)
|
237
|
+
@args_expectation = ArgumentExpectation.new(args, &block)
|
238
|
+
self
|
239
|
+
end
|
240
|
+
|
241
|
+
def exactly(n)
|
242
|
+
set_expected_received_count :exactly, n
|
243
|
+
self
|
244
|
+
end
|
245
|
+
|
246
|
+
def at_least(n)
|
247
|
+
set_expected_received_count :at_least, n
|
248
|
+
self
|
249
|
+
end
|
250
|
+
|
251
|
+
def at_most(n)
|
252
|
+
set_expected_received_count :at_most, n
|
253
|
+
self
|
254
|
+
end
|
255
|
+
|
256
|
+
def times(&block)
|
257
|
+
@method_block = block if block
|
258
|
+
self
|
259
|
+
end
|
260
|
+
|
261
|
+
def any_number_of_times(&block)
|
262
|
+
@method_block = block if block
|
263
|
+
@expected_received_count = :any
|
264
|
+
self
|
265
|
+
end
|
266
|
+
|
267
|
+
def never
|
268
|
+
@expected_received_count = 0
|
269
|
+
self
|
270
|
+
end
|
271
|
+
|
272
|
+
def once(&block)
|
273
|
+
@method_block = block if block
|
274
|
+
@expected_received_count = 1
|
275
|
+
self
|
276
|
+
end
|
277
|
+
|
278
|
+
def twice(&block)
|
279
|
+
@method_block = block if block
|
280
|
+
@expected_received_count = 2
|
281
|
+
self
|
282
|
+
end
|
283
|
+
|
284
|
+
def ordered(&block)
|
285
|
+
@method_block = block if block
|
286
|
+
@order_group.register(self)
|
287
|
+
@ordered = true
|
288
|
+
self
|
289
|
+
end
|
290
|
+
|
291
|
+
def negative_expectation_for?(sym)
|
292
|
+
return false
|
293
|
+
end
|
294
|
+
|
295
|
+
protected
|
296
|
+
def set_expected_received_count(relativity, n)
|
297
|
+
@at_least = (relativity == :at_least)
|
298
|
+
@at_most = (relativity == :at_most)
|
299
|
+
@expected_received_count = case n
|
300
|
+
when Numeric
|
301
|
+
n
|
302
|
+
when :once
|
303
|
+
1
|
304
|
+
when :twice
|
305
|
+
2
|
306
|
+
end
|
307
|
+
end
|
308
|
+
|
309
|
+
def clear_actual_received_count!
|
310
|
+
@actual_received_count = 0
|
311
|
+
end
|
312
|
+
|
313
|
+
end
|
314
|
+
|
315
|
+
class NegativeMessageExpectation < MessageExpectation
|
316
|
+
def initialize(message, expectation_ordering, expected_from, sym, method_block)
|
317
|
+
super(message, expectation_ordering, expected_from, sym, method_block, 0)
|
318
|
+
end
|
319
|
+
|
320
|
+
def negative_expectation_for?(sym)
|
321
|
+
return @sym == sym
|
322
|
+
end
|
323
|
+
end
|
324
|
+
|
325
|
+
end
|
326
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module Rspec
|
2
|
+
module Mocks
|
3
|
+
module Methods
|
4
|
+
def should_receive(sym, opts={}, &block)
|
5
|
+
__mock_proxy.add_message_expectation(opts[:expected_from] || caller(1)[0], sym.to_sym, opts, &block)
|
6
|
+
end
|
7
|
+
|
8
|
+
def should_not_receive(sym, &block)
|
9
|
+
__mock_proxy.add_negative_message_expectation(caller(1)[0], sym.to_sym, &block)
|
10
|
+
end
|
11
|
+
|
12
|
+
def stub!(sym_or_hash, opts={}, &block)
|
13
|
+
if Hash === sym_or_hash
|
14
|
+
sym_or_hash.each {|method, value| stub!(method).and_return value }
|
15
|
+
else
|
16
|
+
__mock_proxy.add_stub(caller(1)[0], sym_or_hash.to_sym, opts, &block)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
alias_method :stub, :stub!
|
21
|
+
|
22
|
+
def stub_chain(*methods)
|
23
|
+
if methods.length > 1
|
24
|
+
next_in_chain = Object.new
|
25
|
+
stub!(methods.shift) {next_in_chain}
|
26
|
+
next_in_chain.stub_chain(*methods)
|
27
|
+
else
|
28
|
+
stub!(methods.shift)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def received_message?(sym, *args, &block) #:nodoc:
|
33
|
+
__mock_proxy.received_message?(sym.to_sym, *args, &block)
|
34
|
+
end
|
35
|
+
|
36
|
+
def rspec_verify #:nodoc:
|
37
|
+
__mock_proxy.verify
|
38
|
+
end
|
39
|
+
|
40
|
+
def rspec_reset #:nodoc:
|
41
|
+
__mock_proxy.reset
|
42
|
+
end
|
43
|
+
|
44
|
+
def as_null_object
|
45
|
+
__mock_proxy.as_null_object
|
46
|
+
end
|
47
|
+
|
48
|
+
def null_object?
|
49
|
+
__mock_proxy.null_object?
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def __mock_proxy
|
55
|
+
if Mock === self
|
56
|
+
@mock_proxy ||= Proxy.new(self, @name, @options)
|
57
|
+
else
|
58
|
+
@mock_proxy ||= Proxy.new(self)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|