🙄
RSpec で任意のメソッドが複数回呼ばれたかどうかと呼び出し順をテストする
前回の続きです。
前回は任意のメソッドが『1回呼ばれたかどうか』を判定していたんですが、『複数回呼ばれたかどうか』は次のようにテストする事ができます。
class X
def hoge
foo "homu"
foo "mami"
foo "mado"
end
def foo(str); end
end
require "rspec"
RSpec.describe X do
describe "#hoge" do
subject { x.hoge }
let(:x) { X.new }
# OK
it do
expect(x).to receive(:foo).with("homu")
expect(x).to receive(:foo).with("mami")
expect(x).to receive(:foo).with("mado")
subject
end
# NG: 呼び出しが足りないと失敗する
it do
expect(x).to receive(:foo).with("homu")
# expect(x).to receive(:foo).with("mami")
expect(x).to receive(:foo).with("mado")
subject
end
# NG: 呼び出しが過剰だと失敗する
it do
expect(x).to receive(:foo).with("homu")
expect(x).to receive(:foo).with("mami")
expect(x).to receive(:foo).with("mado")
expect(x).to receive(:foo).with("saya")
subject
end
end
end
こんな感じで単純に複数回 receive
を使用すればテストする事ができます。
呼び出し順も担保するようにする
上記の書き方の場合は『呼び出し順』までは担保しません。
なので次のようなテストは成功します。
# OK: 順番が違っても成功する
it do
expect(x).to receive(:foo).with("mami")
expect(x).to receive(:foo).with("mado")
expect(x).to receive(:foo).with("homu")
subject
end
もし、メソッドの呼び出し順まで担保したい場合は次のように #ordered
を呼び出すことで担保する事ができます。
# NG: 順番が違っていると失敗する
it do
expect(x).to receive(:foo).with("mami").ordered
expect(x).to receive(:foo).with("mado").ordered
expect(x).to receive(:foo).with("homu").ordered
subject
end
Discussion