I have method returning random value from the predefined array (namely: [ 'value1', 'value2']
).
How should I test that with rspec?
I'd like to do something like:
expect(FooClass.new.value).to be_in ['value1', 'value2']
Any way to do that? Thanks.
Use this
expect(['value1', 'value2']).to include(FooClass.new.value)
Or a simple Boolean match
expect(['value1', 'value2'].include? FooClass.new.value).to be true
Also, there is an or
expect('value').to eq('value1').or eq('value2')
Advantages:
expected: "value1"
got: "value"
...or:
expected: "value2"
got: "value"
As muirbot pointed out you should pass the value you are testing to expect()
, not the other way.
It's more flexible, it will work if someone came here looking for a solution to something like:
expect({one: 1, two: 2, three: 3}).to have_key(:one).or have_key(:first)
If you need this behavior often, you can write your own matcher. Here is the one I wrote - you can stick this in your spec file directly or into any file included by your test suite:
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
This has a nicer failure message than any of the other answers so far (in my opinion). For instance:
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
Or you can customize the error message if some other wording makes more sense to you.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With