a solution similar to thisを実装してデータベースを整理しました。テスト環境でデータベースのソートが間違っていますか?
# model.rb
after_create do
self.class.prune(ENV['VARIABLE_NAME'])
end
def self.prune(max)
order('created_at DESC').last.destroy! until count <= max
end
これは手動テストでうまくいきます。 RSpecので
は、テストは次のようになります
# spec/models/model_spec.rb
before(:each) do
@model = Model.new
end
describe "prune" do
it "should prune the database when it becomes larger than the allowed size" do
25.times { create(:model) }
first_model = model.first
expect{create(:model)}.to change{Model.count}.by(0)
expect{Model.find(first_model.id)}.to raise_error(ActiveRecord::RecordNotFound)
end
end
end
結果は、テスト実行中にデータベースを検査
1) Model prune should prune the database when it becomes larger than the allowed size
Failure/Error: expect{Model.find(first_model.id)}.to raise_error(ActiveRecord::RecordNotFound)
expected ActiveRecord::RecordNotFound but nothing was raised
がorder('created_at DESC').last
への呼び出しがの最初のインスタンスを得ていることが明らかです(モデル#2)で作成されたモデルで、before(:each)
ブロック(モデル#1)で作成されたモデルではありません。私はテストに合格
25.times { sleep(1); create(:model) }
にライン
25.times { create(:model) }
を変更した場合は
。代わりにsleep(0.1)
の場合、テストはまだ失敗します。
これは、私のアプリが1秒以内に2つ以上のモデルインスタンスを作成して、破壊するものを選択するときに最も新しいものを選択するということですか?(最も古いものとは異なり、意図した動作です)これはActiveRecordかMySQLのバグでしょうか?
もしそうでなければ、FactoryGirlやRSpecが生産の代表ではないレコードを作成する方法がありますか?私のテストが現実的なシナリオを表していることを確認するにはどうすればよいですか?
ありがとうございました。私は(非常にばかげたことに)MySQLを格納することを信頼し、ActiveRecordはミリ秒の日付を管理しました。あなたが言うように、それはv 5.6からですが、もちろん私は5.5になっています...これはCentOS 7(?)の安定版のようです。私はあなたのアイデアとcreated_atのソートについて好きです、それは十分です。再度、感謝します – Sam