ruby - Is it possible to have an rspec double with a default response? -
i want mock object might receive number of messages don't care about. i'd object have default answer, such 'true', ability add specific methods , answers matter. possible in rspec? i'd this:
obj = default_double(default: true, widget_count: 5) obj.foobar.should == true obj.widget_count.should == 5
it'd nice if pass in lambda or proc return value , have default_double return evaluation of lambda. extra-nice if proc or lambda evaluated in context of test, access variables available in example.
so if features above added, might have like:
@widgets = widgetcontainer.new @widgets.widget_count = 5 obj = default_double(default: true, widget_count: lambda { @widgets.widget_count }) obj.foobar.should == true obj.widget_count.should == 5
if motivation feature interesting reader, let's assume either don't want dig , find out possible messages receive, or set of possible messages extremely large or unknown.
is built in rspec?
ok, i'll take shot @ answering question:
i believe rspec not have built-in mock capability receive arbitrary message , return default value. however, allow specify return value block which, along ruby's method_missing
feature, should allow readily construct default_double
method describe above.
here's cut @ passes above example, although benefit refactoring:
require 'spec_helper' def default_double(args) object = object.new args.each |key, value| if key == :default object.define_singleton_method(:method_missing) { |method, *args, &block| value } elsif proc === value expect(object).to receive(key) value.call end else expect(object).to receive(key).and_return(value) end end object end class widgetcontainer attr_accessor :widget_count end describe "default_double test" "should pass" @widgets = widgetcontainer.new @widgets.widget_count = 5 obj = default_double(default: true, widget_count: lambda { @widgets.widget_count }) obj.foobar.should == true obj.widget_count.should == 5 end end
Comments
Post a Comment