In my controller''s create method, I have: @sub_context = @context.create_sub_context(params[:context][:name]) If I do not specify params in the "post :create" call in my controller spec then I get the following error for each example: You have a nil object when you didn''t expect it! You might have expected an instance of ActiveRecord::Base. The error occurred while evaluating nil.[] So I see that it is trying to access :name when :context is nil which can be avoided if I ensure each post :create includes a params for [:context][:name] e.g. post :create, :context => {"name" => "Seniors"} I am wondering if there is a way to avoid having to specify params in each and every example by adding some code to a before[:each] block? For example, the params are redundant in some examples e.g. it "should save the context" do @context.should_receive(:save) post :create, :context => {"name" => "Seniors"} end Thanks.
On 12 Jun 2009, at 08:34, Lee wrote:> In my controller''s create method, I have: > > @sub_context = @context.create_sub_context(params[:context][:name]) > > If I do not specify params in the "post :create" call in my controller > spec then I get the following error for each example: > > You have a nil object when you didn''t expect it! > You might have expected an instance of ActiveRecord::Base. > The error occurred while evaluating nil.[] > > So I see that it is trying to access :name when :context is nil which > can be avoided if I ensure each post :create includes a params for > [:context][:name] e.g. > > post :create, :context => {"name" => "Seniors"} > > I am wondering if there is a way to avoid having to specify params in > each and every example by adding some code to a before[:each] block? > For example, the params are redundant in some examples e.g. > > it "should save the context" do > @context.should_receive(:save) > post :create, :context => {"name" => "Seniors"} > end > > Thanks.There are several ways of doing this. The pattern I tend to us is to create a method that does the post, and contains default parameters which you can override if you want to. describe "when the context has a name" def do_post(params = {}) post :create, (:context => {"name" => "Seniors"}).merge(params) end it "should save the context" do @context.should_receive(:save) do_post end end Make sense? Matt Wynne http://beta.songkick.com http://blog.mattwynne.net
Makes perfect sense. Thanks for the tip Matt! On 12 June, 09:43, Matt Wynne <m... at mattwynne.net> wrote:> On 12 Jun 2009, at 08:34, Lee wrote: > > > > > In my controller''s create method, I have: > > > @sub_context = @context.create_sub_context(params[:context][:name]) > > > If I do not specify params in the "post :create" call in my controller > > spec then I get the following error for each example: > > > You have a nil object when you didn''t expect it! > > You might have expected an instance of ActiveRecord::Base. > > The error occurred while evaluating nil.[] > > > So I see that it is trying to access :name when :context is nil which > > can be avoided if I ensure each post :create includes a params for > > [:context][:name] e.g. > > > post :create, :context => {"name" => "Seniors"} > > > I am wondering if there is a way to avoid having to specify params in > > each and every example by adding some code to a before[:each] block? > > For example, the params are redundant in some examples e.g. > > > ? ?it "should save the context" do > > ? ? ?@context.should_receive(:save) > > ? ? ?post :create, :context => {"name" => "Seniors"} > > ? ?end > > > Thanks. > > There are several ways of doing this. The pattern I tend to us is to ? > create a method that does the post, and contains default parameters ? > which you can override if you want to. > > describe "when the context has a name" > ? ?def do_post(params = {}) > ? ? ?post :create, (:context => {"name" => "Seniors"}).merge(params) > ? ?end > > ? ?it "should save the context" do > ? ? ?@context.should_receive(:save) > ? ? ?do_post > ? ?end > end > > Make sense? > > Matt Wynnehttp://beta.songkick.comhttp://blog.mattwynne.net > > _______________________________________________ > rspec-users mailing list > rspec-us... at rubyforge.orghttp://rubyforge.org/mailman/listinfo/rspec-users
On 6/12/09 1:43 AM, Matt Wynne wrote back to Lee who said:>> I am wondering if there is a way to avoid having to specify params in >> each and every example by adding some code to a before[:each] block? > There are several ways of doing this. The pattern I tend to us is to > create a method that does the post, and contains default parameters > which you can override if you want to.For contrast, I''ll describe the method I prefer. The purpose of this approach is to simplify and homogenize the interface of the "do it" routine. By localizing the params in @instance variables, the raw do_action() is a) easily called by you or the shared example group, b) consistently named - the shared example doesn''t have to care what action is being done, and c) overridden with parameters at any level of nested describe()s as you need. describe "something" do before :each do @params = { :default => ''values'' } end sub do_action post :create, @params end it_should_behave_like "some shared example group" # shared example calls back to our do_action, by convention describe "something else" do before do @params[:special_for_something_else] = ''setting'' # other setup end it "whatever" do @params[:special_for_whatever] = ''value'' do_action end end end Randy