RSpec で配列の検証をする方法を整理しておく

問題

RSpec で配列の検証をするのに以下のようなコードを書いた。

describe '#payments' do
  let(:account) { create(:account) }
  let!(:payments) {
    [
      create(:payment_foo, account: account),
      create(:payment_bar, account: account),
      create(:payment_baz, account: account)
    ]
  }  
     
  it 'アカウントに設定された決済方法を返す' do
    expect(account.payments).to include(payments[0], payments[1], payments[2])
  end
end

このテストコードは正しく動作するが、もっとよく書ける。

includeを使っていると「これらの要素を含んでいるけど、他の要素も含まれているかもしれない」と読める。 本当に検証したいのはそうではなくて、これらの要素 だけが 含まれていることを検証したい。

配列の検証をするマッチャいろいろ

eq 配列

eq マッチャ は == を使って比較します。

Array#==

Equality matchers - Built in matchers - RSpec Expectations - RSpec - Relish

match 配列

match マッチャ は match メソッドを使って比較します。

`match` matcher - Built in matchers - RSpec Expectations - RSpec - Relish

ただ、Array や Enumerable には match メソッドがないので、RSpec が実装しているのかなあ??

match_array 配列

match_array マッチャは配列が一致することを検証します。順番は気にしません。

Method: RSpec::Matchers#match_array — Documentation for rspec/rspec-expectations (master)

contain_exactly 配列の要素1, 配列の要素2, ….

contain_exactly マッチャも配列が一致することを検証します。順番は気にしません。

`contain_exactly` matcher - Built in matchers - RSpec Expectations - RSpec - Relish

match_array との違いは引数の指定方法で、以下の2つは同じことを検証します。

expect(results).to contain_exactly(1, 2)
expect(results).to match_array([1, 2])

参考 URL

Ruby - 今日から使える!RSpec 3で追加された8つの新機能 - Qiita

まとめ

いい機会だったので整理してみました。

いつも意図を正確に表現するようにコードを書くことを心がけたいものです。