Object
################################################################# 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.
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
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
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 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 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.
Generated with the Darkfish Rdoc Generator 1.1.6.