マッチャーの組み合わせ
RSpecのマッチャーは、組み合わせて使用することができるように設計されています。これにより、期待する内容の正確な詳細を表現することができますが、それ以上のことは表現しません。これにより、過剰に指定された脆弱な仕様を書くことを避けることができます。マッチャーを使用して、期待する内容の本質的な側面のみを指定します。
以下のマッチャーは、マッチャーを引数として受け入れます。
change { }.by(matcher)
change { }.from(matcher).to(matcher)
contain_exactly(matcher, matcher, matcher)
end_with(matcher, matcher)
include(matcher, matcher)
include(:key => matcher, :other => matcher)
match(arbitrary_nested_structure_with_matchers)
output(matcher).to_stdout
output(matcher).to_stderr
raise_error(ErrorClass, matcher)
start_with(matcher, matcher)
throw_symbol(:sym, matcher)
yield_with_args(matcher, matcher)
yield_successive_args(matcher, matcher)
多くの組み込みマッチャーは、マッチャー引数を受け入れないようになっています。これは、厳密な意味論を持ち、マッチャー引数を許容しないためです。例えば、equal(some_object)
は、実際の引数と期待する引数が同じオブジェクトへの参照である場合にのみパスするように設計されています。ここでは、マッチャー引数をサポートすることは意味がありません。
RSpecの組み込みマッチャーは、名詞句を使用して動詞形ではなく使用することができる1つ以上のエイリアスを持っています。また、失敗時の出力もカスタマイズされており、失敗メッセージも読みやすくなっています。
これらのエイリアスの完全なリストはここでは範囲外ですが、以下にいくつかの使用例を示します。
be < 2
=>a_value < 2
be > 2
=>a_value > 2
be_an_instance_of
=>an_instance_of
be_within
=>a_value_within
contain_exactly
=>a_collection_containing_exactly
end_with
=>a_string_ending_with
,ending_with
match
=>a_string_matching
start_with
=>a_string_starting_with
完全なリストについては、RSpec::Matchers
モジュールのAPIドキュメントを参照してください。
change
を使ったマッチャの組み合わせ
ファイル名が「change_spec.rb」であるファイルが以下の内容であるとき:
RSpec.describe "Passing matchers to `change`" do
specify "you can pass a matcher to `by`" do
k = 0
expect { k += 1.05 }.to change { k }.
by( a_value_within(0.1).of(1.0) )
end
specify "you can pass matchers to `from` and `to`" do
s = "food"
expect { s = "barn" }.to change { s }.
from( a_string_matching(/foo/) ).
to( a_string_matching(/bar/) )
end
end
rspec change_spec.rb
を実行した場合、
全ての例がパスするはずです。
contain_exactly
を使ったマッチャの組み合わせ
ファイル名が「contain_exactly_spec.rb」であるファイルが以下の内容であるとき:
RSpec.describe "Passing matchers to `contain_exactly`" do
specify "you can pass matchers in place of exact values" do
expect(["barn", 2.45]).to contain_exactly(
a_value_within(0.1).of(2.5),
a_string_starting_with("bar")
)
end
end
rspec contain_exactly_spec.rb
を実行した場合、
全ての例がパスするはずです。
end_with
を使ったマッチャの組み合わせ
ファイル名が「end_with_spec.rb」であるファイルが以下の内容であるとき:
RSpec.describe "Passing matchers to `end_with`" do
specify "you can pass matchers in place of exact values" do
expect(["barn", "food", 2.45]).to end_with(
a_string_matching("foo"),
a_value > 2
)
end
end
rspec end_with_spec.rb
を実行した場合、
全ての例がパスするはずです。
include
を使ったマッチャの組み合わせ
ファイル名が「include_spec.rb」であるファイルが以下の内容であるとき:
RSpec.describe "Passing matchers to `include`" do
specify "you can use matchers in place of array values" do
expect(["barn", 2.45]).to include( a_string_starting_with("bar") )
end
specify "you can use matchers in place of hash values" do
expect(:a => "food", :b => "good").to include(:a => a_string_matching(/foo/))
end
specify "you can use matchers in place of hash keys" do
expect("food" => "is good").to include( a_string_matching(/foo/) )
end
end
rspec include_spec.rb
を実行した場合、
全ての例がパスするはずです。
match
を使ったマッチャの組み合わせ
ファイル名が「match_spec.rb」であるファイルが以下の内容であるとき:
RSpec.describe "Passing matchers to `match`" do
specify "you can match nested data structures against matchers" do
hash = {
:a => {
:b => ["foo", 5.0],
:c => { :d => 2.05 }
}
}
expect(hash).to match(
:a => {
:b => a_collection_containing_exactly(
a_string_starting_with("f"),
an_instance_of(Float)
),
:c => { :d => (a_value < 3) }
}
)
end
end
rspec match_spec.rb
を実行した場合、
全ての例がパスするはずです。
output
を使ったマッチャの組み合わせ
ファイル名が「output_spec.rb」であるファイルが以下の内容であるとき:
RSpec.describe "Passing matchers to `output`" do
specify "you can pass a matcher in place of the output (to_stdout)" do
expect {
print 'foo'
}.to output(a_string_starting_with('f')).to_stdout
end
specify "you can pass a matcher in place of the output (to_stderr)" do
expect {
warn 'foo'
}.to output(a_string_starting_with('f')).to_stderr
end
end
rspec output_spec.rb
を実行した場合、
全ての例がパスするはずです。
raise_error
を使ったマッチャの組み合わせ
ファイル名が「raise_error_spec.rb」であるファイルが以下の内容であるとき:
RSpec.describe "Passing matchers to `raise_error`" do
specify "you can pass a matcher in place of the message" do
expect {
raise RuntimeError, "this goes boom"
}.to raise_error(RuntimeError, a_string_ending_with("boom"))
end
end
rspec raise_error_spec.rb
を実行した場合、
全ての例がパスするはずです。
start_with
を使ったマッチャの組み合わせ
ファイル名が「start_with_spec.rb」であるファイルが以下の内容であるとき:
RSpec.describe "Passing matchers to `start_with`" do
specify "you can pass matchers in place of exact values" do
expect(["barn", "food", 2.45]).to start_with(
a_string_matching("bar"),
a_string_matching("foo")
)
end
end
rspec start_with_spec.rb
を実行した場合、
全ての例がパスするはずです。