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