62 lines
2.2 KiB
Markdown
62 lines
2.2 KiB
Markdown
+++
|
|
date = "2011-09-25"
|
|
title = "Properly testing Rails 3 scopes"
|
|
tags = ["Ruby on Rails", "Rails", "rspec", "rails3", "scope", "named_scope"]
|
|
slug = "properly-testing-rails-3-scopes"
|
|
+++
|
|
<p class="important">The content of this post is no longer correct. Please read <a href="http://ariejan.net/2011/10/09/testing-rails-3-scopes-revisited">this article</a> for details.</p>
|
|
|
|
Testing scopes has always felt a bit weird to me. Normally I'd do something like this:
|
|
|
|
``` ruby
|
|
class Post < ActiveRecord::Base
|
|
scope :published, where(:published => true)
|
|
scope :latest, order("created_at DESC")
|
|
end
|
|
|
|
describe Post do
|
|
context 'scopes' do
|
|
before(:all) do
|
|
@first = FactoryGirl.create(:post, :created_at => 1.day.ago, :published => true)
|
|
@last = FactoryGirl.create(:post, :created_at => 4.day.ago, :published => false)
|
|
end
|
|
|
|
it "should only return published posts" do
|
|
Post.published.should == [@first]
|
|
end
|
|
|
|
it "should return posts in the correct order" do
|
|
Post.latest.should == [@first, @last]
|
|
end
|
|
end
|
|
end
|
|
```
|
|
|
|
This test is okay. It tests if the named scope does what it needs to do. And there's also the problem. Scopes are part of ActiveRecord and are already extensively tested there. All we need to do is check if we _configure_ the scope correctly.
|
|
|
|
What we need is a way to inspect what `where` and `order` rules are set for a particular scope and make sure those are the correct ones. We can then trust ActiveRecord to keep its promise to execute the proper SQL query for us.
|
|
|
|
Here's another test that utilizes some Rails 3 methods you may not have heard of before.
|
|
|
|
``` ruby
|
|
describe Post do
|
|
context 'scopes' do
|
|
it "should only return published posts" do
|
|
Post.published.where_values_hash.should == {:published => true}
|
|
end
|
|
|
|
it "should return posts in the correct order" do
|
|
Post.latest.order_values.should == ["created_at DESC"]
|
|
end
|
|
end
|
|
end
|
|
```
|
|
|
|
The `where_values_hash` and `order_values` allow you to inspect what a scopes doing. By writing your test this way you achieve two import goals:
|
|
|
|
1. You test _your_ code (instead of the ActiveRecord)
|
|
2. You don't use the database, which is a significant speed boost
|
|
|
|
Happy testing to you all!
|
|
|