rspec-mocksメモ

モックに使えるメソッドのメモ。 この記事ではスタブ、ダブル、モックなどのワードを厳密に区別しません。 ここに書いている内容はほとんど公式ドキュメントからの抜粋です。 https://rspec.info/features/3-12/rspec-mocks/ double 1 dbl = double("Hoge") doubleメソッドでダブルオブジェクトを作成できます。 これだけではメソッド呼び出しに対応できないので、receiveメソッドで振る舞いを定義します。 1 2 3 dbl = double("Hoge") allow(dbl).to receive(:foo).and_return("bar")` dbl.foo # => "bar" doubleは実オブジェクトに存在しないメソッドも定義できます。 これを避けたい場合は、次に上げるinstance_doubleが使えます。 instance_double 1 2 3 4 5 6 dbl = instance_double("String") allow(dbl).to receive(:length).and_return(5) dbl.length # => 5 # Stringオブジェクトに存在しないので、エラーになる allow(dbl).to receive(:hoge).and_return(5) 実オブジェクトの一部の振る舞いを差し替えたいことが多いと思うので、基本的にはinstance_doubleを使うのが良いでしょう。 クラスメソッドに対しては、class_doubleがあります。 ...

2025-10-21 · 2 min · ksaito

RSpecのdefine_negated_matcherでカスタムマッチャーの否定形を定義する

RSpecのdefine_negated_matcherを使うと、カスタムマッチャーの否定形を簡単に定義できます。 not_toが使えないような複合条件のケースを作成する際に便利です。 このようなケースを想定しています。 1 2 3 4 5 6 RSpec.describe [1, 2, 3] do it '' do lists = subject.dup expect { lists.delete(2) }.to change { lists }.not_to include(2) end end 実行すると、次のエラーが発生します。 NotImplementedError: `expect { }.not_to change { }.to()` is not supported このようなケースでは次のように書けば変わらんだろうというツッコミはさておき、直接的に検証したい場合は、define_negated_matcherを使って否定形のマッチャーを定義することで解決できます。 1 expect { lists.delete(2) }.to change { lists }.to contain_exactly(1, 3) 使い方 1 2 3 4 5 6 7 8 9 RSpec::Matchers.define_negated_matcher :an_array_excluding, :include RSpec.describe [1, 2, 3] do it '' do lists = subject.dup expect { lists.delete(2) }.to change { lists }.to an_array_excluding(2) expect { lists.delete(2) }.to change { lists }.to contain_exactly(1, 3) end end これだけでOKです。 listsは変更されて、2が含まれなくなることを検証できます。

2025-10-20 · 1 min · ksaito

RSpecで配列を検証するときのマッチャーの使い分け

毎回調べているのでいい加減整理しておきたい。 サマリ 先に結果を書いておく。 配列の要素が一致し、かつ、並び順は問わない: contain_exactly match_arrayでも同じ 配列の要素が一致し、かつ、並び順も一致する: eq 配列の要素が部分的に一致する: include contain_exactly / match_array 配列の要素が一致し、かつ、並び順は問わない 1 2 3 4 5 6 7 8 9 RSpec.describe [1, 2, 3] do it '' do is_expected.to contain_exactly(1, 2, 3) is_expected.to contain_exactly(3, 2, 1) is_expected.not_to contain_exactly(1) is_expected.to match_array([3, 2, 1]) end end eq 配列の要素が一致し、かつ、並び順も一致する ...

2025-10-19 · 1 min · ksaito