Misoca のコードレビューで教えてもらった RSpec マッチャまとめ

この記事は Misoca+弥生 Advent Calendar 2019 の7日目の記事です。

はじめに

Misoca に入社して1年とちょっとが経ちました。 Misoca は Ruby がメインの会社です。 私のキャリアはずっと Java だったので、特に RSpec の知識が貧弱で、RSpec は「expect って書くのは知ってる…」ぐらいの知識でした。 RSpec のマッチャは数も多く、いったいどこから勉強したらよいのか…というままテストコードを書いたため、コードレビューでよりよい書き方を教えてもらいつつやってきました。 そこで、同じ指摘をもらわないように自分用にまとめつつ、同じような境遇の人に少しでも役に立つように、Misoca のコードレビューで教えてもらった RSpec の書き方を紹介します。

注意事項として、以下で書き換え前と後のコードが出てきますが、どちらが良い悪いという意図はありません。 実際、指摘をもらっても書き換えることもあれば、メリットがあればそのままにすることもありました。

be_xxx

target が xxx? というメソッドを持っている場合、 be_xxx というマッチャが使えます。 例えば

expect(target.persisted?).to be_truthy

という example があったら

expect(target).to be_persisted

と書くことができます。

and

and マッチャをつなげることで expect(target) を何度も書かなくてすみます。 例えば

expect(target).to be_cool
expect(target).to be_beautiful

という example があったら

expect(target).to be_cool
  .and be_beautiful

と書くことできます。

have_attributes

have_attributes マッチャを使うことで複数の属性を持つことを一気にチェックできます。 例えば

expect(target.name).to eq('mallowlabs')
expect(target.company).to eq('Misoca Inc.')
expect(target.joined_at).to eq('2018-10-01')

という example があったら

expect(target).to have_attributes(
  name: 'mallowlabs',
  company: 'Misoca Inc.',
  joined_at: '2018-10-01'
)

と書くことができます。

all

all マッチャを使うことでコレクションの要素を一気にチェックできます。

targets.each do |target|
  expect(target).to be_ok
end

という example があったら

expect(targets).to all(be_ok)

と書くことできます。

satisfy

satisfy マッチャを使うことでブロックをマッチャに変換して all マッチャに渡すことができます。 例えば

targets.each do |target|
  expect(target).not_to be_cool
end

という example があったら

expect(targets).to all(satisfy { |t| !t.cool? })

と書くことができます。

contain_exactly

contain_exactly マッチャを使うことでコレクションの中に要素がすべて含まれているかを確認できます。 コレクションの長さを確認しつつ、要素が意図したものが入っているかのチェックする際に

array = ['mallowlabs']
expect(array.size).to eq(1)
expect(array.first).to eq('mallowlabs')

という example を書いていました。これは

array = ['mallowlabs']
expect(array).to contain_exactly('mallowlabs')

のように書けます。

他にも

いろんなマッチャを教えてもらいましたが、シンプルに説明できなかったので割愛します。

まとめ

洗練されていないコードを書いても dis られることなく、建設的な提案をしてくれる Misoca の開発メンバーのみんなに感謝です。

明日は id:ryotaway が「BrainF***処理系を作ってみます」という記事を買いてくれるそうです。楽しみですね。