rspec - 其中一个选择的匹配器

时间:2014-10-28 07:17:22

标签: ruby rspec

我有从预定义数组返回随机值的方法(即:[ 'value1', 'value2'])。 我应该如何使用rspec进行测试?

我想做点什么:

expect(FooClass.new.value).to be_in ['value1', 'value2']

有什么办法吗?感谢。

4 个答案:

答案 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')

优点:

  1. 听起来像普通的英语。
  2. 错误消息有点长,但包含所有相关信息:
expected: "value1"
    got: "value"

...or:

expected: "value2"
    got: "value"
  1. 正如 muirbot 指出的,您应该将正在测试的值传递给 expect(),而不是相反。

  2. 它更灵活,如果有人来这里寻找解决方案,它会起作用:

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) }

当测试失败时,这还会给您更准确的信息。