[rspec-users] Writing controller specs

Hans de Graaff hans at degraaff.org
Thu Nov 1 15:50:41 EDT 2007


One thing that is bothering me about my controller specs is that
sometimes I end up with a number of examples that are the same except
for the example name.

The reason that this happens is that I've expressed all the expected
behavior with should_receive. While this does more or less work as
intended it doesn't feel right.

As an example, let's say I'm writing code to post a comment and record
the IP address. First, let's handle the comment posting:


describe 'post comment' do

  before do
    @data = {'text' => 'A comment that is posted'}
    @comment = mock_model(Comment)
  end

  it 'should be successful when proper input has been given' do
    Comment.should_receive(:new).with(@data).once.and_return(@comment)
    @comment.should_receive(:save).and_return(true)

    post :create, {:comment => @data}
    response.should be_success
  end
end


So far so good, although checking the response doesn't feel exactly
right. 
Then again, the two expectations already cover the example, so checking
the
response could just as well be left out.

Now, on to adding the recording of the IP address:

  it 'should record the IP address of the poster' do
    @comment.should_receive(:ip_address=).with('0.0.0.0')

    post :create, {:comment => @data}
  end

Obviously this won't work because the @comment object has not been set
up correctly. So, we should also add in that code:

  it 'should record the IP address of the poster' do
    Comment.should_receive(:new).with(@data).once.and_return(@comment)
    @comment.should_receive(:save).and_return(true)
    @comment.should_receive(:ip_address=).with('0.0.0.0')

    post :create, {:comment => @data}
  end
  
But now the initial example won't work anymore because the mock model
doesn't deal with the ip_address= method. Let's fix that as well:

  it 'should be successful when proper input has been given' do
    Comment.should_receive(:new).with(@data).once.and_return(@comment)
    @comment.should_receive(:save).and_return(true)
    @comment.should_receive(:ip_address=).with('0.0.0.0')

    post :create, {:comment => @data}
    response.should be_success
  end

So now both methods look the same (minus the gratuitous response
check) and it feels like something went wrong somewhere. It even
becomes tempting to move the should_receive lines into the before-do
block, but then the examples become essentially empty.

Any comments on insight into this would be appreciated.

Kind regards,

Hans
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: This is a digitally signed message part
Url : http://rubyforge.org/pipermail/rspec-users/attachments/20071101/8b479d27/attachment.bin 


More information about the rspec-users mailing list