FactoryBotを使用してRSpecでRailsモデルの名前付きスコープをテストしようとしています。複数のレコードを作成していますが、スコープから返されるのは1つだけです。
RSpec.describe GemNamespace::GemModel, type: :model do
before(:all)
FactoryBot.create(:gem_model, :trait1) # id 1
FactoryBot.create(:gem_model, :trait2) # id 2
FactoryBot.create(:gem_model, :trait3) # id 3
end
let(:included_record) { GemNamespace::GemModel.find 1 }
describe 'my_named_scope' do
it 'returns only records matching the conditions' do
scope_results = GemNamespace::GemModel.my_named_scope
expect(scope_results).to contain_exactly(included_record)
end
end
end
のincluded_record
唯一のレコードであるにもかかわらずscope_results
、一部のデバッグではincluded_record
、何らかの理由で結果のRubyオブジェクトとは実際には異なるRubyオブジェクトであることが示されているため、テストは失敗しています。したがって、contain_exactlyは失敗します。
私はこのようなスコープテストを多数のモデルで実行しましたが、常に機能しています。これとの唯一の違いは、モデルがgem内で定義されていることと、Railsアプリで名前付きスコープをモデルに追加することでその機能を拡張していることです。
何が足りないのですか?このモデルだけでこのように動作するのはなぜですか?
重要な場合:
- Ruby 2.5.0
- Rails 5.1.5
- rspec 3.7.0
- rspec-rails 3.7.2
- factory_bot(_rails)4.8.2
更新:上記を編集する代わりに、これをここに配置します。私は実際にテーブルではなくデータベースビューをテストしています。ビューには一意のID列がないため、実際にはGemNamespace::GemModel.find 1
上記を実行していませんが、代わりにwhere(column: <condition value>)
。
私は回避策でこれを解決しました。Railsの内部についてはあまりよくわかりませんが、データベースビュー(および対応するモデル)にid
列がないため、問題が発生しているようです(つまり、個別のRubyオブジェクトが作成されています)。したがって、2つのオブジェクトのすべての値を「手動で」比較しただけです。
# As a workaround, we're just gonna convert them both to Ruby hashes using
# the #as_json method, and compare those instead.
expect(scope_results.as_json).to contain_exactly(included_record.as_json)
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加