Skip to content

Instantly share code, notes, and snippets.

@krohrbaugh
Created June 3, 2015 21:37
Show Gist options
  • Save krohrbaugh/0a2fa8bbf34d4e7a56cd to your computer and use it in GitHub Desktop.
Save krohrbaugh/0a2fa8bbf34d4e7a56cd to your computer and use it in GitHub Desktop.
RSpec Query Limit matcher
# Allows for assertions regarding number of queries executed.
#
# Usage:
# it "eager loads `#manager` association" do
# expect do
# employee = Employee.with_manager.find(employee_id)
# employee.manager
# end.to satisfy_query_limit(1)
# end
RSpec::Matchers.define :satisfy_query_limit do |expected|
match do |block|
count_queries(&block) <= expected
end
failure_message_for_should do |actual|
"Expected to execute no more than #{expected} SQL queries, got #{@query_count}"
end
failure_message_for_should_not do |actual|
"Expected to execute more than #{expected} SQL queries, got #{@query_count}"
end
def count_queries
@query_count = 0
filter_list = %w[CACHE SCHEMA]
# Rails 3.2 introduces ActiveSupport::Notifications::subscribed for temporary
# subscribers. Use that for 3.2+
query_counter = ->(name, started, finished, unique_id, payload) do
@query_count += 1 unless payload[:name].in?(filter_list)
end
subscriber = ActiveSupport::Notifications.subscribe("sql.active_record", query_counter)
yield
ActiveSupport::Notifications.unsubscribe(subscriber)
@query_count
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment