[RSpec, Rails] POST create action spec and before_filter


#1

Hello,

I face the following problem for a POST create action spec.

I have this controller: http://pastie.org/482270

I wrote this spec: http://pastie.org/482273

The spec “should set @context” works fine.

But when running the spec “should build a new message” I got this error:

<Page(id: integer, title: string, content: text, created_at: datetime,
updated_at: datetime) (class)> expected :new with
({“title”=>“Introduction”,
“content”=>“page d’introduction”}) once, but received it 0 time

I can not find why Page model does not receive new call, and playing
around
I can have the spec running successfully when I remove :create from the
before_filter line!
#before_filter :get_context_from_session, :only => [:new, :create,
:index]
before_filter :get_context_from_session, :only => [:new, :index]

It does not make sense for me. I probably miss something but I can not
find
what.

Any ideas? Thanks by advance :slight_smile:

Regards,
Florent


#2

2009-05-18 21:40, Florent F.rent:

I have this controller: http://pastie.org/482270
I wrote this spec: http://pastie.org/482273

There are a few spots which draw my attention. At spec line 4 you
create a mock Page with #save that always fails (succesfull save
returns true). Is that intentional? At line 9 you .and_return a
value from a variable you don’t set anywhere. Moreover the “should
set @context” is imo a spec smell (even though it’s in description
string), because it refers to internal state of a PagesController
instance, which you should not be interested in, but the external
behavior.

The spec “should set @context” works fine. But when running the
spec “should build a new message” I got this error:

<Page(id: integer, title: string, content: text, created_at:
datetime, updated_at: datetime) (class)> expected :new with
({“title”=>“Introduction”, “content”=>“page d’introduction”}) once,
but received it 0 time

Could that have something to do with the fact that you end up stubbing
Page.new one or two times before setting the expectation on it at line
14? It shouldn’t, but you never know.

I can not find why Page model does not receive new call, and playing
around I can have the spec running successfully when I remove
:create from the before_filter line!

Could your filter be failing and the failure not showin up somehow?
Does “should set @contextreally succeed? Comment the other
example one out and then try again. Generally you shouldn’t expect
your examples (or specs) to run in any particular order.


#3

2009/5/19 Florent F.rent removed_email_address@domain.invalid

Do you mean I should change the wording as something “should set the
context”, in order no to refer to a internal behaviour?

Well, I’ve just moved this filter to my application controller and now
in my
PageController spec I just specify the call to the filter.


#4

2009/5/19 Tero T. removed_email_address@domain.invalid

2009-05-18 21:40, Florent F.rent:

I have this controller: http://pastie.org/482270
I wrote this spec: http://pastie.org/482273

There are a few spots which draw my attention. At spec line 4 you
create a mock Page with #save that always fails (succesfull save
returns true). Is that intentional?

No, it is mistake (copy/paste from another controller spec). I’ve
corrected
in
@page = mock_model(Page)

At line 9 you .and_return a

value from a variable you don’t set anywhere.

Right, I’ve changed it in
Context.should_receive(:find).and_return mock_model(Context)

Moreover the “should
set @context” is imo a spec smell (even though it’s in description
string), because it refers to internal state of a PagesController
instance, which you should not be interested in, but the external
behavior.

Do you mean I should change the wording as something “should set the
context”, in order no to refer to a internal behaviour?

Could that have something to do with the fact that you end up stubbing
your examples (or specs) to run in any particular order.
You are right, the filter was failing. I had to add
@context = mock_model(Context)
Context.stub!(:find).and_return @context
in a before block so that the filter really works.

Thanks for your help! :slight_smile:

BTW how can I spec that my @context is correctly set by my filter? I add
this in the spec “should set the context”:
assigns[:context].should == @context

but it returns the error “You have a nil object when you didn’t expect
it!
The error occurred while evaluating nil.assigns”.

Florent


#5

2009-05-19 10:22, Florent F.rent:

BTW how can I spec that my @context is correctly set by my filter?

How can you tell from outside if the context is properly set or not?
What does your controller use the context for? And what happens if
the controller does or doesn’t know about the context?