yield
匹配器
有四个相关的匹配器,允许您指定方法是否产生值,产生值的次数,是否产生带参数的值,以及参数是什么。
yield_control
匹配如果被测方法产生值,无论是否产生参数。yield_with_args
匹配如果被测方法产生带参数的值。如果此匹配器提供参数,它将仅在实际产生的参数使用===
或==
与预期参数匹配时通过。yield_with_no_args
匹配如果被测方法产生无参数的值。yield_successive_args
专门用于迭代器,如果被测方法产生的次数与传递给此匹配器的参数一样多,并且所有实际产生的参数都使用===
或==
与预期参数匹配,则将匹配。
注意:您的 expect 块*必须*接受一个参数,该参数随后作为块传递给被测方法。这充当一个“探测器”,允许匹配器检测您的方法是否产生值,以及如果产生值,产生的次数和产生的参数是什么。
背景
给定一个名为“my_class.rb”的文件,其中包含
class MyClass
def self.yield_once_with(*args)
yield *args
end
def self.yield_twice_with(*args)
2.times { yield *args }
end
def self.raw_yield
yield
end
def self.dont_yield
end
end
yield_control
匹配器
给定一个名为“yield_control_spec.rb”的文件,其中包含
require './my_class'
RSpec.describe "yield_control matcher" do
specify { expect { |b| MyClass.yield_once_with(1, &b) }.to yield_control }
specify { expect { |b| MyClass.dont_yield(&b) }.not_to yield_control }
specify { expect { |b| MyClass.yield_twice_with(1, &b) }.to yield_control.twice }
specify { expect { |b| MyClass.yield_twice_with(1, &b) }.to yield_control.exactly(2).times }
specify { expect { |b| MyClass.yield_twice_with(1, &b) }.to yield_control.at_least(1) }
specify { expect { |b| MyClass.yield_twice_with(1, &b) }.to yield_control.at_most(3).times }
# deliberate failures
specify { expect { |b| MyClass.yield_once_with(1, &b) }.not_to yield_control }
specify { expect { |b| MyClass.dont_yield(&b) }.to yield_control }
specify { expect { |b| MyClass.yield_once_with(1, &b) }.to yield_control.at_least(2).times }
specify { expect { |b| MyClass.yield_twice_with(1, &b) }.not_to yield_control.twice }
specify { expect { |b| MyClass.yield_twice_with(1, &b) }.not_to yield_control.at_least(2).times }
specify { expect { |b| MyClass.yield_twice_with(1, &b) }.not_to yield_control.at_least(1) }
specify { expect { |b| MyClass.yield_twice_with(1, &b) }.not_to yield_control.at_most(3).times }
end
当我运行rspec yield_control_spec.rb
那么输出应该包含所有这些
13 个示例,7 个失败 |
期望给定块产生控制 |
期望给定块不产生控制 |
期望给定块不产生至少两次控制 |
期望给定块不产生最多 3 次控制 |
yield_with_args
匹配器
给定一个名为“yield_with_args_spec.rb”的文件,其中包含
require './my_class'
RSpec.describe "yield_with_args matcher" do
specify { expect { |b| MyClass.yield_once_with("foo", &b) }.to yield_with_args }
specify { expect { |b| MyClass.yield_once_with("foo", &b) }.to yield_with_args("foo") }
specify { expect { |b| MyClass.yield_once_with("foo", &b) }.to yield_with_args(String) }
specify { expect { |b| MyClass.yield_once_with("foo", &b) }.to yield_with_args(/oo/) }
specify { expect { |b| MyClass.yield_once_with("foo", "bar", &b) }.to yield_with_args("foo", "bar") }
specify { expect { |b| MyClass.yield_once_with("foo", "bar", &b) }.to yield_with_args(String, String) }
specify { expect { |b| MyClass.yield_once_with("foo", "bar", &b) }.to yield_with_args(/fo/, /ar/) }
specify { expect { |b| MyClass.yield_once_with("foo", "bar", &b) }.not_to yield_with_args(17, "baz") }
# deliberate failures
specify { expect { |b| MyClass.yield_once_with("foo", &b) }.not_to yield_with_args }
specify { expect { |b| MyClass.yield_once_with("foo", &b) }.not_to yield_with_args("foo") }
specify { expect { |b| MyClass.yield_once_with("foo", &b) }.not_to yield_with_args(String) }
specify { expect { |b| MyClass.yield_once_with("foo", &b) }.not_to yield_with_args(/oo/) }
specify { expect { |b| MyClass.yield_once_with("foo", "bar", &b) }.not_to yield_with_args("foo", "bar") }
specify { expect { |b| MyClass.yield_once_with("foo", "bar", &b) }.to yield_with_args(17, "baz") }
end
当我运行rspec yield_with_args_spec.rb
那么输出应该包含所有这些
14 个示例,6 个失败 |
期望给定块不产生带参数的值,但产生了 |
期望给定块不产生带参数的值,但产生了预期参数 |
期望给定块产生带参数的值,但产生了意外参数 |
yield_with_no_args
匹配器
给定一个名为“yield_with_no_args_spec.rb”的文件,其中包含
require './my_class'
RSpec.describe "yield_with_no_args matcher" do
specify { expect { |b| MyClass.raw_yield(&b) }.to yield_with_no_args }
specify { expect { |b| MyClass.dont_yield(&b) }.not_to yield_with_no_args }
specify { expect { |b| MyClass.yield_once_with("a", &b) }.not_to yield_with_no_args }
# deliberate failures
specify { expect { |b| MyClass.raw_yield(&b) }.not_to yield_with_no_args }
specify { expect { |b| MyClass.dont_yield(&b) }.to yield_with_no_args }
specify { expect { |b| MyClass.yield_once_with("a", &b) }.to yield_with_no_args }
end
当我运行rspec yield_with_no_args_spec.rb
那么输出应该包含所有这些
6 个示例,3 个失败 |
期望给定块不产生无参数的值,但产生了 |
期望给定块产生无参数的值,但没有产生 |
期望给定块产生无参数的值,但产生了带参数的值:["a"] |
yield_successive_args
匹配器
给定一个名为“yield_successive_args_spec.rb”的文件,其中包含
def array
[1, 2, 3]
end
def array_of_tuples
[[:a, :b], [:c, :d]]
end
RSpec.describe "yield_successive_args matcher" do
specify { expect { |b| array.each(&b) }.to yield_successive_args(1, 2, 3) }
specify { expect { |b| array_of_tuples.each(&b) }.to yield_successive_args([:a, :b], [:c, :d]) }
specify { expect { |b| array.each(&b) }.to yield_successive_args(Integer, Integer, Integer) }
specify { expect { |b| array.each(&b) }.not_to yield_successive_args(1, 2) }
# deliberate failures
specify { expect { |b| array.each(&b) }.not_to yield_successive_args(1, 2, 3) }
specify { expect { |b| array_of_tuples.each(&b) }.not_to yield_successive_args([:a, :b], [:c, :d]) }
specify { expect { |b| array.each(&b) }.not_to yield_successive_args(Integer, Integer, Integer) }
specify { expect { |b| array.each(&b) }.to yield_successive_args(1, 2) }
end
当我运行rspec yield_successive_args_spec.rb
那么输出应该包含所有这些
8 个示例,4 个失败 |
期望给定块不产生带参数的连续值,但产生了预期参数 |
期望给定块产生带参数的连续值,但产生了意外参数 |