respond_to
匹配器
使用 respond_to
匹配器来指定对象接口的详细信息。 在最基本的形式中
expect(obj).to respond_to(:foo) # pass if obj.respond_to?(:foo)
您可以在单个语句中指定对象响应多个消息,并将多个参数传递给匹配器
expect(obj).to respond_to(:foo, :bar) # passes if obj.respond_to?(:foo) && obj.respond_to?(:bar)
如果方法接受的参数数量对您很重要,您也可以指定该数量
expect(obj).to respond_to(:foo).with(1).argument
expect(obj).to respond_to(:bar).with(2).arguments
expect(obj).to respond_to(:baz).with(1..2).arguments
expect(obj).to respond_to(:xyz).with_unlimited_arguments
如果您的 Ruby 版本支持关键字参数,您可以指定方法接受的关键字列表。
expect(obj).to respond_to(:foo).with_keywords(:ichi, :ni)
expect(obj).to respond_to(:bar).with(2).arguments.and_keywords(:san, :yon)
expect(obj).to respond_to(:baz).with_arbitrary_keywords
请注意,此匹配器完全依赖于 #respond_to?
。 如果对象通过 #method_missing
动态响应消息,但没有通过 #respond_to?
指示这一点,那么此匹配器将为您提供错误的结果。
基本用法
给定一个名为“respond_to_matcher_spec.rb”的文件,其中包含
RSpec.describe "a string" do
it { is_expected.to respond_to(:length) }
it { is_expected.to respond_to(:hash, :class, :to_s) }
it { is_expected.not_to respond_to(:to_model) }
it { is_expected.not_to respond_to(:compact, :flatten) }
# deliberate failures
it { is_expected.to respond_to(:to_model) }
it { is_expected.to respond_to(:compact, :flatten) }
it { is_expected.not_to respond_to(:length) }
it { is_expected.not_to respond_to(:hash, :class, :to_s) }
# mixed examples--String responds to :length but not :flatten
# both specs should fail
it { is_expected.to respond_to(:length, :flatten) }
it { is_expected.not_to respond_to(:length, :flatten) }
end
当我运行 rspec respond_to_matcher_spec.rb
那么输出应该包含所有这些
10 个示例,6 个失败 |
期望“一个字符串”响应 :to_model |
期望“一个字符串”响应 :compact, :flatten |
期望“一个字符串”不响应 :length |
期望“一个字符串”不响应 :hash, :class, :to_s |
期望“一个字符串”响应 :flatten |
期望“一个字符串”不响应 :length |
指定参数
给定一个名为“respond_to_matcher_argument_checking_spec.rb”的文件,其中包含
RSpec.describe 7 do
it { is_expected.to respond_to(:zero?).with(0).arguments }
it { is_expected.not_to respond_to(:zero?).with(1).argument }
it { is_expected.to respond_to(:between?).with(2).arguments }
it { is_expected.not_to respond_to(:between?).with(7).arguments }
# deliberate failures
it { is_expected.to respond_to(:zero?).with(1).argument }
it { is_expected.not_to respond_to(:zero?).with(0).arguments }
it { is_expected.to respond_to(:between?).with(7).arguments }
it { is_expected.not_to respond_to(:between?).with(2).arguments }
end
当我运行 rspec respond_to_matcher_argument_checking_spec.rb
那么输出应该包含所有这些
8 个示例,4 个失败 |
期望 7 响应 :zero? 具有 1 个参数 |
期望 7 不响应 :zero? 具有 0 个参数 |
期望 7 响应 :between? 具有 7 个参数 |
期望 7 不响应 :between? 具有 2 个参数 |
指定参数范围
给定一个名为“respond_to_matcher_argument_range_checking_spec.rb”的文件,其中包含
class MyClass
def build(name, options = {})
end
def inspect
'my_object'
end
end
RSpec.describe MyClass do
it { is_expected.to respond_to(:build).with(1..2).arguments }
it { is_expected.not_to respond_to(:build).with(0..1).arguments }
it { is_expected.not_to respond_to(:build).with(2..3).arguments }
it { is_expected.not_to respond_to(:build).with(0..3).arguments }
# deliberate failures
it { is_expected.not_to respond_to(:build).with(1..2).arguments }
it { is_expected.to respond_to(:build).with(0..1).arguments }
it { is_expected.to respond_to(:build).with(2..3).arguments }
it { is_expected.to respond_to(:build).with(0..3).arguments }
end
当我运行 rspec respond_to_matcher_argument_range_checking_spec.rb
那么输出应该包含所有这些
8 个示例,4 个失败 |
期望 my_object 不响应 :build 具有 1..2 个参数 |
期望 my_object 响应 :build 具有 0..1 个参数 |
期望 my_object 响应 :build 具有 2..3 个参数 |
期望 my_object 响应 :build 具有 0..3 个参数 |
指定无限参数
给定一个名为“respond_to_matcher_unlimited_argument_checking_spec.rb”的文件,其中包含
class MyClass
def greet(message = 'Hello', *people)
end
def hail(person)
end
def inspect
'my_object'
end
end
RSpec.describe MyClass do
it { is_expected.to respond_to(:greet).with_unlimited_arguments }
it { is_expected.to respond_to(:greet).with(1).argument.and_unlimited_arguments }
it { is_expected.not_to respond_to(:hail).with_unlimited_arguments }
it { is_expected.not_to respond_to(:hail).with(1).argument.and_unlimited_arguments }
# deliberate failures
it { is_expected.not_to respond_to(:greet).with_unlimited_arguments }
it { is_expected.not_to respond_to(:greet).with(1).argument.and_unlimited_arguments }
it { is_expected.to respond_to(:hail).with_unlimited_arguments }
it { is_expected.to respond_to(:hail).with(1).argument.and_unlimited_arguments }
end
当我运行 rspec respond_to_matcher_unlimited_argument_checking_spec.rb
那么输出应该包含所有这些
8 个示例,4 个失败 |
期望 my_object 不响应 :greet 具有无限参数 |
期望 my_object 不响应 :greet 具有 1 个参数和无限参数 |
期望 my_object 响应 :hail 具有无限参数 |
期望 my_object 响应 :hail 具有 1 个参数和无限参数 |
指定关键字
给定一个名为“respond_to_matcher_keyword_checking_spec.rb”的文件,其中包含
class MyClass
def find(name = 'id', limit: 1_000, offset: 0)
[]
end
def inspect
'my_object'
end
end
RSpec.describe MyClass do
it { is_expected.to respond_to(:find).with_keywords(:limit, :offset) }
it { is_expected.to respond_to(:find).with(1).argument.and_keywords(:limit, :offset) }
it { is_expected.not_to respond_to(:find).with_keywords(:limit, :offset, :page) }
it { is_expected.not_to respond_to(:find).with(1).argument.and_keywords(:limit, :offset, :page) }
# deliberate failures
it { is_expected.to respond_to(:find).with_keywords(:limit, :offset, :page) }
it { is_expected.to respond_to(:find).with(1).argument.and_keywords(:limit, :offset, :page) }
it { is_expected.not_to respond_to(:find).with_keywords(:limit, :offset) }
it { is_expected.not_to respond_to(:find).with(1).argument.and_keywords(:limit, :offset) }
end
当我运行 rspec respond_to_matcher_keyword_checking_spec.rb
那么输出应该包含所有这些
8 个示例,4 个失败 |
期望 my_object 响应 :find 具有关键字 :limit, :offset 和 :page |
期望 my_object 响应 :find 具有 1 个参数和关键字 :limit, :offset 和 :page |
期望 my_object 不响应 :find 具有关键字 :limit 和 :offset |
期望 my_object 不响应 :find 具有 1 个参数和关键字 :limit 和 :offset |
指定任何关键字
给定一个名为“respond_to_matcher_any_keywords_checking_spec.rb”的文件,其中包含
class MyClass
def build(name: 'object', **opts)
end
def create(name: 'object', type: String)
end
def inspect
'my_object'
end
end
RSpec.describe MyClass do
it { is_expected.to respond_to(:build).with_any_keywords }
it { is_expected.to respond_to(:build).with_keywords(:name).and_any_keywords }
it { is_expected.not_to respond_to(:create).with_any_keywords }
it { is_expected.not_to respond_to(:create).with_keywords(:name).and_any_keywords }
# deliberate failures
it { is_expected.not_to respond_to(:build).with_any_keywords }
it { is_expected.not_to respond_to(:build).with_keywords(:name).and_any_keywords }
it { is_expected.to respond_to(:create).with_any_keywords }
it { is_expected.to respond_to(:create).with_keywords(:name).and_any_keywords }
end
当我运行 rspec respond_to_matcher_any_keywords_checking_spec.rb
那么输出应该包含所有这些
8 个示例,4 个失败 |
期望 my_object 不响应 :build 具有任何关键字 |
期望 my_object 不响应 :build 具有关键字 :name 和任何关键字 |
期望 my_object 响应 :create 具有任何关键字 |
期望 my_object 响应 :create 具有关键字 :name 和任何关键字 |
指定必需关键字
给定一个名为“respond_to_matcher_required_keyword_checking_spec.rb”的文件,其中包含
class MyClass
def plant(seed:, fertilizer: nil, water: 'daily')
[]
end
def inspect
'my_object'
end
end
RSpec.describe MyClass do
it { is_expected.to respond_to(:plant).with_keywords(:seed) }
it { is_expected.to respond_to(:plant).with_keywords(:seed, :fertilizer, :water) }
it { is_expected.not_to respond_to(:plant).with_keywords(:fertilizer, :water) }
# deliberate failures
it { is_expected.not_to respond_to(:plant).with_keywords(:seed) }
it { is_expected.not_to respond_to(:plant).with_keywords(:seed, :fertilizer, :water) }
it { is_expected.to respond_to(:plant).with_keywords(:fertilizer, :water) }
end
当我运行 rspec respond_to_matcher_required_keyword_checking_spec.rb
那么输出应该包含所有这些
6 个示例,3 个失败 |
期望 my_object 不响应 :plant 具有关键字 :seed |
期望 my_object 不响应 :plant 具有关键字 :seed, :fertilizer 和 :water |
期望 my_object 响应 :plant 具有关键字 :fertilizer 和 :water |