我有一个测试套件,有太多这样的断言
expect(array_1).to match_array array_2
expect(array_3).to match_array array_4
expect(array_5).to match_array array_5
等等。
我希望将这些检查包装在自定义匹配器中,但在该自定义匹配器中,我希望使用match_array
匹配器,因为我真的很喜欢它返回的错误消息,列出了缺失和额外元素的情况。不匹配。
这样的事情:
RSpec::Matchers.define :have_data do |data|
match do |actual|
actual.eql? data # I don't want to do this.
actual.match_array? data # <<- I'd like do do something like this to retain the matcher behaviour
end
end
我能做到这一点吗?当然,match_array?
并不存在。
答案 0 :(得分:1)
查看match_array
匹配器的实现:
# An alternate form of `contain_exactly` that accepts
# the expected contents as a single array arg rather
# that splatted out as individual items.
#
# @example
# expect(results).to contain_exactly(1, 2)
# # is identical to:
# expect(results).to match_array([1, 2])
#
# @see #contain_exactly
def match_array(items)
contain_exactly(*items)
end
contain_exactly
方法调用Rspec::BuiltIn::ContainExactly
模块:
def contain_exactly(*items)
BuiltIn::ContainExactly.new(items)
end
您可以使用对此模块的调用来迭代您需要匹配的数据,并仍然使用match_array
方法中的错误消息。
或者,您可以基于BuiltIn::ContainExactly
module实现自己的模块。
答案 1 :(得分:0)
我想使用contain_exactly功能,将实际数组重新映射为数组项的id。这类似于您要尝试执行的操作,因此也许会有所帮助。我把它放在/support/matchers/match_array_ids.rb
中。
module MyMatchers
class MatchArrayIds < RSpec::Matchers::BuiltIn::ContainExactly
def match_when_sorted?
values_match?(safe_sort(expected), safe_sort(actual.map(&:id)))
end
end
def match_array_ids(items)
MatchArrayIds.new(items)
end
end
我还创建了一个测试以测试匹配器是否按预期运行。我把它放在spec/matcher_tests/match_array_ids_spec.rb
中。
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe MyMatchers::MatchArrayIds do
before do
class ObjectWithId
attr_reader :id
def initialize(id)
@id = id
end
end
end
context 'when array of objects with ids and array of ids match' do
let(:objects_with_ids) { [ObjectWithId.new('id1'), ObjectWithId.new('id2')] }
let(:ids) { ['id1', 'id2'] }
it 'returns true' do
expect(objects_with_ids).to match_array_ids(ids)
end
end
context 'when array of objects with ids exist and array of ids is empty' do
let(:objects_with_ids) { [ObjectWithId.new('id1'), ObjectWithId.new('id2')] }
let(:ids) { [] }
it 'returns false' do
expect(objects_with_ids).not_to match_array_ids(ids)
end
end
context 'when array of objects with ids is empty and array of ids exist' do
let(:objects_with_ids) { [] }
let(:ids) { ['id1', 'id2'] }
it 'returns false' do
expect(objects_with_ids).not_to match_array_ids(ids)
end
end
context 'when array of objects with ids and array of ids DO NOT match' do
let(:objects_with_ids) { [ObjectWithId.new('id1'), ObjectWithId.new('id2')] }
let(:ids) { ['id1', 'id3'] }
it 'returns false' do
expect(objects_with_ids).not_to match_array_ids(ids)
end
end
end
您可以在以下位置找到基于此内容的示例,该示例基于便签匹配器进行自定义... https://github.com/rspec/rspec-expectations/blob/45e5070c797fb4cb6166c8daca2ea68e31aeca40/lib/rspec/matchers.rb#L145-L196