Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Rails and Rspec, how do you test that the database is not touched by a method

So I'm writing a test for a method which for performance reasons should achieve what it needs to achieve without using SQL queries. I'm thinking all I need to know is what to stub:

describe SomeModel do
  describe 'a_getter_method' do
    it 'should not touch the database' do
      thing = SomeModel.create

      something_inside_rails.should_not_receive(:a_method_querying_the_database)

      thing.a_getter_method
    end
  end
end

EDIT: to provide a more specific example:

class Publication << ActiveRecord::Base
end
class Book << Publication
end
class Magazine << Publication
end

class Student << ActiveRecord::Base
  has_many :publications

  def publications_of_type(type)
    #this is the method I am trying to test.  
    #The test should show that when I do the following, the database is queried.

    self.publications.find_all_by_type(type)
  end
end


describe Student do
  describe "publications_of_type" do
    it 'should not touch the database' do
       Student.create()
       student = Student.first(:include => :publications)
       #the publications relationship is already loaded, so no need to touch the DB

       lambda {
         student.publications_of_type(:magazine)
       }.should_not touch_the_database
    end
  end
end

So the test should fail in this example, because the rails 'find_all_by' method relies on SQL.

like image 970
Will Tomlins Avatar asked Feb 19 '23 11:02

Will Tomlins


2 Answers

SomeModel.should_not_receive(:connection) should do it.

like image 103
histocrat Avatar answered May 08 '23 07:05

histocrat


I know this question is super old now, but I stumbled across it trying to do the same thing. After looking around some more I've found there's a great and simple gem for this.

https://github.com/brigade/db-query-matchers

It adds an rspec matcher that takes a block so you can just use:

expect { subject.make_no_queries }.to_not make_database_queries

The configuration is super simple too, and it means you can have some calls that do make queries mixed in with a subset of calls that do connect to the database.

like image 43
Alex Ives Avatar answered May 08 '23 05:05

Alex Ives