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 212
212:     def add_model_methods(mock, model_class, id)
213:       container = mock.flexmock_container
214: 
215:       mock_errors = container.flexmock("errors")
216:       mock_errors.should_receive(:count).and_return(0).by_default
217:       mock_errors.should_receive(:full_messages).and_return([]).by_default
218: 
219:       mock.should_receive(:id).and_return(id).by_default
220:       mock.should_receive(:to_params).and_return(id.to_s).by_default
221:       mock.should_receive(:new_record?).and_return(false).by_default
222:       mock.should_receive(:class).and_return(model_class).by_default
223:       mock.should_receive(:errors).and_return(mock_errors).by_default
224: 
225:       # HACK: Ruby 1.9 needs the following lambda so that model_class
226:       # is correctly bound below.
227:       lambda { }
228:       mock.should_receive(:is_a?).with(any).and_return { |other|
229:         other == model_class
230:       }.by_default
231:       mock.should_receive(:instance_of?).with(any).and_return { |other|
232:         other == model_class
233:       }.by_default
234:       mock.should_receive(:kind_of?).with(any).and_return { |other|
235:         model_class.ancestors.include?(other)
236:       }.by_default
237:     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 241
241:     def make_partial_proxy(container, obj, name, safe_mode)
242:       name ||= "flexmock(#{obj.class.to_s})"
243:       obj.instance_eval {
244:         mock = FlexMock.new(name, container)
245:         @flexmock_proxy ||= PartialMockProxy.new(obj, mock, safe_mode)
246:       }
247:       obj.instance_variable_get("@flexmock_proxy")
248:     end
next_id() click to toggle source

Return the next id for mocked models.

     # File lib/flexmock/mock_container.rb, line 181
181:     def next_id
182:       @id_counter ||= 10000
183:       @id_counter += 1
184:     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 286
286:     def build_demeter_chain(mock, arg, &block)
287:       container = mock.flexmock_container
288:       names = arg.to_s.split('.')
289:       check_method_names(names)
290:       exp = nil
291:       next_exp = lambda { |n| block.call(n) }
292:       loop do
293:         method_name = names.shift.to_sym
294:         exp = mock.flexmock_find_expectation(method_name)
295:         need_new_exp = exp.nil? || names.empty?
296:         exp = next_exp.call(method_name) if need_new_exp
297:         break if names.empty?
298:         if need_new_exp
299:           mock = container.flexmock("demeter_#{method_name}")
300:           exp.with_no_args.and_return(mock)
301:         else
302:           mock = exp._return_value([])
303:         end
304:         check_proper_mock(mock, method_name)
305:         next_exp = lambda { |n| mock.should_receive(n) }
306:       end
307:       exp
308:     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 321
321:     def check_method_names(names)
322:       names.each do |name|
323:         fail FlexMock::UsageError, "Ill-formed method name '#{name}'" if
324:           name !~ METHOD_NAME_RE
325:       end
326:     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 311
311:     def check_proper_mock(mock, method_name)
312:       unless mock.kind_of?(FlexMock)
313:         fail FlexMock::UsageError,
314:           "Conflicting mock declaration for '#{method_name}' in demeter style mock"
315:       end
316:     end

Disabled; run with --debug to generate this.

[Validate]

Generated with the Darkfish Rdoc Generator 1.1.6.