経緯
rspecのassignsテストでランダムで要素を取得する変数をテストする際に、以下の方法で実装したので備忘録としてメモ。他に何かいい方法がありましたらコメントしていただけたら嬉しいです。
self - other -> Array
rubyで特定の配列から指定した要素を取り除いた要素を返す。
使用例
[1, 2, 3, 4, 5] - [3, 4] # => [1, 2, 5]
実際の使用
コントローラー
@related_products = Spree::Product.in_taxons(@product.taxons).
includes(master: [:images, :default_price]).
where.not(id: @product.id).distinct.sample(4)
コントローラーspec
let(:taxonomy) { create(:taxonomy) }
let(:taxon1) { create(:taxon, taxonomy: taxonomy) }
let(:taxon2) { create(:taxon, taxonomy: taxonomy) }
let(:taxon3) { create(:taxon, taxonomy: taxonomy) }
let(:taxon4) { create(:taxon, taxonomy: taxonomy) }
let(:product) { create(:product, taxons: [taxon1, taxon3, taxon4]) }
let!(:related_product1) { create(:product, taxons: [taxon1, taxon3, taxon4]) }
let!(:related_product2) { create(:product, taxons: [taxon1, taxon3]) }
let!(:related_product3) { create(:product, taxons: [taxon1, taxon4]) }
let!(:related_product4) { create(:product, taxons: [taxon1]) }
let!(:related_product5) { create(:product, taxons: [taxon1]) }
let!(:unrelated_product) { create(:product, taxons: [taxon2]) }
it "assigns only related products" do
all_related_products = [
related_product1,
related_product2,
related_product3,
related_product4,
related_product5
]
# (関連商品をランダムに4つ取得するrelated_productsから関連商品全てを除けば空になるはず
# →関連商品のみ割り当てられているはず)
expect(assigns(:related_products) - all_related_products).to be_empty
end
assignsのテストはランダムとか要素数を絞ると途端に難しくなるな〜といった印象。
# 参考
https://qiita.com/jnchito/items/2e79a1abe7cd8214caa5#eq
https://docs.ruby-lang.org/ja/latest/class/Array.html#I_--2D