RailsでREST APIを作成しています。私は RSpec を使用しています。データベース呼び出しの数を最小限に抑えたいので、特定のアクションの一部として実行されるデータベース呼び出しの数を検証する自動テストを追加したいと考えています。それを私のテストに追加する簡単な方法はありますか? 私が探しているのは、単一の API 呼び出しの結果としてデータベースに対して行われている呼び出しを監視/記録する方法です。これが RSpec では実行できなくても、他のテスト ツールで実行できる場合、それも素晴らしいことです。
質問する
1933 次
4 に答える
3
Rails 3 で最も簡単なのは、おそらく通知 API にフックすることです。
この加入者
class SqlCounter< ActiveSupport::LogSubscriber
def self.count= value
Thread.current['query_count'] = value
end
def self.count
Thread.current['query_count'] || 0
end
def self.reset_count
result, self.count = self.count, 0
result
end
def sql(event)
self.class.count += 1
puts "logged #{event.payload[:sql]}"
end
end
SqlCounter.attach_to :active_record
実行されたすべてのSQLステートメントをコンソールに出力してカウントします。次に、次のような仕様を書くことができます
expect do
# do stuff
end.to change(SqlCounter, :count).by(2)
テーブルの構造を決定するために、トランザクションを開始/コミットするステートメントや、アクティブ レコードが発行するステートメントなど、いくつかのステートメントを除外したい場合があります。
于 2012-06-29T21:05:54.910 に答える
1
Explainの使用に興味があるかもしれません。しかし、それは自動ではありません。各アクションを手動で分析する必要があります。しかし、重要なのは db 呼び出しの数ではなく、その性質であるため、これは良いことかもしれません。例: インデックスを使用していますか?
これをチェックして:
http://weblog.rubyonrails.org/2011/12/6/what-s-new-in-edge-rails-explain/
于 2012-06-29T20:38:54.640 に答える
0
Fredrick の答えは私にとってはうまくいきましたが、私の場合は、各 ActiveRecord クラスの呼び出し数も個別に知りたいと思っていました。他の人に役立つ場合に備えて、いくつかの変更を加えて、これになりました。
class SqlCounter< ActiveSupport::LogSubscriber
# Returns the number of database "Loads" for a given ActiveRecord class.
def self.count(clazz)
name = clazz.name + ' Load'
Thread.current['log'] ||= {}
Thread.current['log'][name] || 0
end
# Returns a list of ActiveRecord classes that were counted.
def self.counted_classes
log = Thread.current['log']
loads = log.keys.select {|key| key =~ /Load$/ }
loads.map { |key| Object.const_get(key.split.first) }
end
def self.reset_count
Thread.current['log'] = {}
end
def sql(event)
name = event.payload[:name]
Thread.current['log'] ||= {}
Thread.current['log'][name] ||= 0
Thread.current['log'][name] += 1
end
end
SqlCounter.attach_to :active_record
expect do
# do stuff
end.to change(SqlCounter, :count).by(2)
于 2014-10-06T23:49:51.667 に答える