我正在运行一堆数据驱动的规范,并且预期的数据在不同的类中(因为我有时必须使用Regexps,因为输出字符串每次都会更改,但始终遵循特定的格式)。
一个完美地检查它们的表达式是Ruby的大小写相等运算符===
。问题是,与大多数Ruby表达式相比,它可以向后运行,有时操作是不对称的:
/rgx a/ === b # equivalent to b =~ /rgx a/
ClassA === b # equivalent to b.is_a? ClassA
在我的规范中,这意味着我必须将操作数放错:
[Class, /regex/, 'string'].each do |expected_data|
it { expect(expected_data).to be === actual_data }
end
这会导致错误的错误消息:
expected: === "Actual data"
got: "Expected data"
有没有办法扭转 ===
运算符或 expect
语法?
答案 0 :(得分:1)
如果归结为它,你可以为此定义自己的匹配器:
describe 'reverse case eq' do
it { expect('regex').to reverse_case_eq /regex/ }
it { expect('bad match').to reverse_case_eq /regex/ } # fails
end
RSpec::Matchers.define :reverse_case_eq do |expected|
match do |actual|
expected === actual
end
end
在这种情况下的错误消息如下所示:
Failure/Error: it { expect('bad match').to reverse_case_eq /regex/ } expected "bad match" to reverse case eq /regex/
您也可以添加
failure_message do |actual|
"expected #{expected.inspect} to === #{actual.inspect}"
end
到define块,然后失败消息将成为
Failure/Error: it { expect('bad match').to reverse_case_eq /regex/ } expected /regex/ to === "bad match"
如果您经常遇到此用例,可能会首选。
答案 1 :(得分:0)
事实证明,RSpec具有非常灵活的satisfy matcher。我可以按如下方式更改expect
语法,它完全符合我的需要:
expect(actual_data).to satisfy { |v| expected_data === v }
(已编辑 - 感谢@Glyoko)默认失败消息稍微过于迟钝(expected [actual data] to satisfy block
),但您也可以将说明传递给#satisfy
:
expect(actual_data).to satisfy("match #{expected_data}") { |v| expected_data === v }
规范的默认说明(即如果您没有将说明传递给#it
)则为[context/description] should match [expected data]
,失败邮件为expected [actual data] to match [expected data]
。