この記事は 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***処理系を作ってみます」という記事を買いてくれるそうです。楽しみですね。