组合匹配器
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 的内置匹配器都具有一个或多个别名,这些别名允许您使用名词短语而不是动词形式,因为它们在作为组合参数时读起来更好。它们还提供自定义的失败输出,以便失败消息也读起来更好。
这里没有列出所有这些别名,但下面列出了一些用于以下示例的别名
* `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
那么这些示例应该全部通过。
使用 throw_symbol
组合匹配器
给定一个名为“throw_symbol_spec.rb”的文件,其中包含
RSpec.describe "Passing matchers to `throw_symbol`" do
specify "you can pass a matcher in place of a throw arg" do
expect {
throw :pi, Math::PI
}.to throw_symbol(:pi, a_value_within(0.01).of(3.14))
end
end
当我运行 rspec throw_symbol_spec.rb
那么这些示例应该全部通过。
使用 yield_with_args
组合匹配器
给定一个名为“yield_with_args_spec.rb”的文件,其中包含
RSpec.describe "Passing matchers to `yield_with_args`" do
specify "you can pass matchers in place of the args" do
expect { |probe|
"food".tap(&probe)
}.to yield_with_args(a_string_matching(/foo/))
end
end
当我运行 rspec yield_with_args_spec.rb
那么这些示例应该全部通过。
使用 yield_successive_args
组合匹配器
给定一个名为“yield_successive_args_spec.rb”的文件,其中包含
RSpec.describe "Passing matchers to `yield_successive_args`" do
specify "you can pass matchers in place of the args" do
expect { |probe|
[1, 2, 3].each(&probe)
}.to yield_successive_args(a_value < 2, 2, a_value > 2)
end
end
当我运行 rspec yield_successive_args_spec.rb
那么这些示例应该全部通过。
使用复合 and
表达式组合匹配器
给定一个名为“include_spec.rb”的文件,其中包含
RSpec.describe "Passing a compound matcher expression to `include`" do
example do
expect(["food", "drink"]).to include( a_string_starting_with("f").and ending_with("d"))
end
end
当我运行 rspec include_spec.rb
那么这些示例应该全部通过。