我有从预定义数组返回随机值的方法(即:[ 'value1', 'value2']
)。
我应该如何使用rspec进行测试?
我想做点什么:
expect(FooClass.new.value).to be_in ['value1', 'value2']
有什么办法吗?感谢。
答案 0 :(得分:6)
使用此
expect(['value1', 'value2']).to include(FooClass.new.value)
或简单的布尔匹配
expect(['value1', 'value2'].include? FooClass.new.value).to be true
答案 1 :(得分:3)
如果您经常需要此行为,则可以编写自己的匹配器。这是我写的-您可以将其直接粘贴到您的spec文件中,也可以粘贴到测试套件所包含的任何文件中:
RSpec::Matchers.define(:be_one_of) do |expected|
match do |actual|
expected.include?(actual)
end
failure_message do |actual|
"expected one of #{expected}, got #{actual}"
end
end
与到目前为止的其他答案相比,这有一个更好的失败消息(我认为)。例如:
Failures:
1) mydata is either empty or a list
Failure/Error: expect(mydata.class).to(be_one_of([NilClass, Array]))
expected one of [NilClass, Array], got String
或者,如果您认为其他措辞更有意义,则可以自定义错误消息。
答案 2 :(得分:2)
此外,还有一个 or
expect('value').to eq('value1').or eq('value2')
优点:
expected: "value1"
got: "value"
...or:
expected: "value2"
got: "value"
正如 muirbot 指出的,您应该将正在测试的值传递给 expect()
,而不是相反。
它更灵活,如果有人来这里寻找解决方案,它会起作用:
expect({one: 1, two: 2, three: 3}).to have_key(:one).or have_key(:first)
答案 3 :(得分:1)
这确实有效,但非常规,因为传递给expect
的值应该是您正在测试的值。
expect(['value1', 'value2']).to include(FooClass.new.value)
我认为这样做会更好
expect(Foo.new.value).to satisfy { |value| ['value1', 'value2'].include?(value) }
当测试失败时,这还会给您更准确的信息。