How to Have Rspec Test for My Default Scope

How can i have rspec test for my default scope

I would rather have this tested using a query and checking the results, but if you really must do it, one possible solution would be something like this for Rails 3:

CatMembership.scoped.to_sql.should == CatMembership.order(:created_at).to_sql

And on Rails 2:

CatMembership.default_scoping.should == [{:create=>{}, :find=>{:order=>"created_at"}}]

But I would not say these solutions are ideal since they show a lot of knowledge of the implementation (and you can see the implementation varies with different Rails versions).

Creating sample data, running an usual all query and checking the result is correctly ordered might have been simpler, would be closer to real unit testing and would work even as you upgrade your rails version.

In this case it would possibly be:

before do
@memberships = []

@memberships << CatMembership.create!
@memberships << CatMembership.create!
@memberships << CatMembership.create!

[ 1.hour.ago, 5.minutes.ago, 1.minute.ago ].each_with_index do |time, index|
membership = @memberships[index]
membership.created_at = time
membership.save
end

end

it 'should be correctly ordered' do
@sorted_memberships = CatMembership.all
@memberships.first.should == @sorted_memberships.last
@memberships.second.should == @sorted_memberships.second
@memberships.third.should == @sorted_memberships.first
end

It's much more verbose, but it's going to work even as you move forward on rails.

And now I have just noticed who asked the question :D

Testing Default scope in RSpec

A better way to test your default scope is to use real data with an expected output. Create dummy objects for your class, then query the class and compare the result to what you expect to be the correct order:

describe 'default scope' do
let!(:book_one) { Book.create(name: "The Count of Monte Cristo") }
let!(:book_two) { Book.create(name: "Animal Farm") }

it 'orders by ascending name' do
Book.all.should eq [book_two, book_one]
end
end

let!(:book_one) creates an instance of Book and assigns it to a local variable called book_one. Its name attribute is The Count of Monte Cristo. let!(:book_two) does something similar.

If the default order is name ASC, then querying the Book model should return an ActiveRecord relation with book_two as the first element ("Animal..."), and book_one as the second element ("The C...").

We can test this expectation as follows:

Book.all.should eq [book_two, book_one]

This does not test your SQL, but it tests the direct output of your code, which is more useful. It is also database independent.

Testing default scope in Rails

you could so something along the lines of this:

context "scopes" do
describe "default_scope" do
before do
create(:user, active_status: true)
create(:user, active_status: false)
}

context "with default scope" do
subject { User.all }

it { should have(1).user }
end

context "without default scope" do
subject { User.unscoped.all }

it { should have(2).users }
end
end
end

note: I'm using RSpec and FactoryGirl.

note2: You can consider this as an anti pattern, because the default_scope is a protected method. But this is what you asked for.

Rails: Testing named scopes with RSpec

The creator of RSpec has recently blogged he thinks Validations are behavior, associations are structure. In other words he finds that associations (and scopes) should not nessesarily be tested directly. Tests for these will follow from the behavior you want.

In other words, current wisdom is that there is no need to test each scope directly, since you will cover these associations by testing the behavior of your application.

how to write rspec test for scope in model

You can test this kind of thing by making a collection, and then doing

expect(Mymodel.scope).to match_array(expected_collection)

Rails –Testing named scopes: test scope results or scope configuration?

I think you have described the problem very well, and that the best answer, in my opinion is - it depends.

If your scope is trivial, run-of-the-mill where, with some order, etc. there is no real need to test ActiveRecord or the database to make sure they work properly - you can safely assume that they have been correctly implemented, and simply test the structure you expect.

If, on the other hand, your scope (or any query) is compound, or uses advanced features in a complex configuration, I believe that setting up tests that assert its behavior, by using a real live database (which is installed locally, with a small custom-tailored data set) can go a long way in assuring you that your code works.

It will also help you, if and when you decide to change strategies (use that cool new mysql feature, or porting to postgresql), to refactor safely, by checking that the functionality is robust.

This is a much better way than to simply verify the the SQL string is what you typed there...

How to test scopes?

David Chelimsky (Rspec's creator) offered up the following example in the Rspec Google Group:

describe User, ".admins" do 
it "includes users with admin flag" do
admin = User.create! :admin => true
User.admin.should include(admin)
end

it "excludes users without admin flag" do
non_admin = User.create! :admin => false
User.admin.should_not include(non_admin)
end
end

class User < ActiveRecord::Base
named_scope :admins, :conditions => {:admin => true}
end

It's obviously not the same example as yours, but it should give you an idea of how to do it. The relevant thread for context is here: http://groups.google.com/group/rspec/browse_thread/thread/6706c3f2cceef97f



Related Topics



Leave a reply



Submit