Can I set params in before[:each] block?

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:

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 W.

http://blog.mattwynne.net

Makes perfect sense. Thanks for the tip Matt!

On 6/12/09 1:43 AM, Matt W. 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