10

Oct

RSpec Tutorial Part 5 - Advanced Testing Tips

If you still feel like you're hacking RSpec when you want to be slicing and dicing, here are some helpful tips:

1. Ever done something ugly like this?

  old_count = Article.count
  @article.tags.create(...)
  Article.count.should == old_count+1

Here's a better way:

  lambda { @article.tags.create(...) }.should change(Article, :count).by(1)

Other possibilities include:

  lambda { @article.tags.create(...) }.should change(Article, :count).from(0).to(1)
  lambda { @article.title = 'new title' }.should change(@article, :title).to('new title')

2. Ever done this in TestUnit?

  assert_raises (ActiveRecord::RecordNotFound) do
    Article.find(0)
  end

Here's how you can do that in rspec:

  lamda{ Article.find(0) }.should raise_error(ActiveRecord::RecordNotFound)

3. Ever done a view test like this and thought you were testing something useful?

  response.should have_tag("div#listings") do
    with_tag("a", :attributes => {:href => "/articles/#{ fi.id}" })
  end

Here's what you really did:

  response.should have_tag("div#listings") do
    with_tag("a")
  end

Not very impressive is it? Here's what you were looking for:

  response.should have_tag("div#listings") do
    with_tag("a[href=?]", "/articles/1")
  end

Or with a regular expression:

  response.should have_tag("div#listings") do
     with_tag("a[href*=?]", /^http.*some.*regexp/i)
 end

4. Something else to watch out for:

  @article.should.respond_to(:tags)

This doesn't actually test the association of tags on an article. Typically, 'should's should never have a '.' after them in Rspec. TestSpec, on the other hand, does support that.

What does test the association is this:

  @article.should respond_to(:tags)