Parent

Included Modules

FlexMock::MockContainerHelper

################################################################# Helper methods for mock containers. MockContainer is a module that is designed to be mixed into other classes, particularly testing framework test cases. Since we don’t want to pollute the method namespace of the class that mixes in MockContainer, a number of MockContainer methods were moved into ContainerHelper to to isoloate the names.

Constants

METHOD_NAME_RE

Public Instance Methods

add_model_methods(mock, model_class, id) click to toggle source

Automatically add mocks for some common methods in ActiveRecord models.

     # File lib/flexmock/mock_container.rb, line 222
222:     def add_model_methods(mock, model_class, id)
223:       container = mock.flexmock_container
224: 
225:       mock_errors = container.flexmock("errors")
226:       mock_errors.should_receive(:count).and_return(0).by_default
227:       mock_errors.should_receive(:full_messages).and_return([]).by_default
228: 
229:       mock.should_receive(:id).and_return(id).by_default
230:       mock.should_receive(:to_params).and_return(id.to_s).by_default
231:       mock.should_receive(:new_record?).and_return(false).by_default
232:       mock.should_receive(:class).and_return(model_class).by_default
233:       mock.should_receive(:errors).and_return(mock_errors).by_default
234: 
235:       # HACK: Ruby 1.9 needs the following lambda so that model_class
236:       # is correctly bound below.
237:       lambda { }
238:       mock.should_receive(:is_a?).with(any).and_return { |other|
239:         other == model_class
240:       }.by_default
241:       mock.should_receive(:instance_of?).with(any).and_return { |other|
242:         other == model_class
243:       }.by_default
244:       mock.should_receive(:kind_of?).with(any).and_return { |other|
245:         model_class.ancestors.include?(other)
246:       }.by_default
247:     end
make_partial_proxy(container, obj, name, safe_mode) click to toggle source

Create a PartialMockProxy for the given object. Use name as the name of the mock object.

     # File lib/flexmock/mock_container.rb, line 251
251:     def make_partial_proxy(container, obj, name, safe_mode)
252:       name ||= "flexmock(#{obj.class.to_s})"
253:       if !obj.instance_variable_defined?("@flexmock_proxy") || obj.instance_variable_get("@flexmock_proxy").nil?
254:         mock = FlexMock.new(name, container)
255:         proxy = PartialMockProxy.new(obj, mock, safe_mode)
256:         obj.instance_variable_set("@flexmock_proxy", proxy)
257:       end
258:       obj.instance_variable_get("@flexmock_proxy")
259:     end
next_id() click to toggle source

Return the next id for mocked models.

     # File lib/flexmock/mock_container.rb, line 191
191:     def next_id
192:       @id_counter ||= 10000
193:       @id_counter += 1
194:     end

Private Instance Methods

build_demeter_chain(mock, arg, &block) click to toggle source

Build the chain of mocks for demeter style mocking.

Warning: Nasty code ahead.

This method builds a chain of mocks to support demeter style mocking. Given a mock chain of “first.second.third.last“, we must build a chain of mock methods that return the next mock in the chain. The expectation for the last method of the chain is returned as the result of the method.

Things to consider:

(1) The expectation for the “first” method must be created by the proper mechanism, which is supplied by the block parameter “block”. In other words, first expectation is created by calling the block. (This allows us to create expectations on both pure mocks and partial mocks, with the block handling the details).

(2) Although the first mock is arbitrary, the remaining mocks in the chain will always be pure mocks created specifically for this purpose.

(3) The expectations for all methods but the last in the chain will be setup to expect no parameters and to return the next mock in the chain.

(4) It could very well be the case that several demeter chains will be defined on a single mock object, and those chains could share some of the same methods (e.g. “mock.one.two.read“ and “mock.one.two.write“ both share the methods “one” and “two”). It is important that the shared methods return the same mocks in both chains.

     # File lib/flexmock/mock_container.rb, line 297
297:     def build_demeter_chain(mock, arg, &block)
298:       container = mock.flexmock_container
299:       names = arg.to_s.split('.')
300:       check_method_names(names)
301:       exp = nil
302:       next_exp = lambda { |n| block.call(n) }
303:       loop do
304:         method_name = names.shift.to_sym
305:         exp = mock.flexmock_find_expectation(method_name)
306:         need_new_exp = exp.nil? || names.empty?
307:         exp = next_exp.call(method_name) if need_new_exp
308:         break if names.empty?
309:         if need_new_exp
310:           mock = container.flexmock("demeter_#{method_name}")
311:           exp.with_no_args.and_return(mock)
312:         else
313:           mock = exp._return_value([])
314:         end
315:         check_proper_mock(mock, method_name)
316:         next_exp = lambda { |n| mock.should_receive(n) }
317:       end
318:       exp
319:     end
check_method_names(names) click to toggle source

Check that all the names in the list are valid method names.

     # File lib/flexmock/mock_container.rb, line 332
332:     def check_method_names(names)
333:       names.each do |name|
334:         fail FlexMock::UsageError, "Ill-formed method name '#{name}'" if
335:           name !~ METHOD_NAME_RE
336:       end
337:     end
check_proper_mock(mock, method_name) click to toggle source

Check that the given mock is a real FlexMock mock.

     # File lib/flexmock/mock_container.rb, line 322
322:     def check_proper_mock(mock, method_name)
323:       unless mock.kind_of?(FlexMock)
324:         fail FlexMock::UsageError,
325:           "Conflicting mock declaration for '#{method_name}' in demeter style mock"
326:       end
327:     end

Disabled; run with --debug to generate this.

[Validate]

Generated with the Darkfish Rdoc Generator 1.1.6.