0

A Ruby spec defines 3 instance_doubles:

let(:doub1) { instance_double(Foo) }
let(:doub2) { instance_double(Foo) }
let(:doub3) { instance_double(Foo) }

A shared_example seeks to ensure a collaborator is used with any of the instance_doubles:

shared_examples :a_consumer_of_bars do
  it "passes a Foo to the BarGetter" do
    expect(BarGetter).to receive(:fetch_bar)
      .with((condition1 || condition2 || condition3)).at_least(:once)
    subject
  end
end

The (piped||arguments||approach) does not work. Is there an existing rspec matcher for checking whether an argument matches an element of an array? Or is writing a custom matcher the way to go?

Todd R
  • 18,236
  • 8
  • 31
  • 39

2 Answers2

0

I would go with a custom matcher as it looks very unusual.

The piped||arguments||approach obviously doesn't work, because it returns first non-false element. In your case whichever of the doubles is first in the pipe || order.

Also, it makes me wonder why you need something like this, don't you have full control over your specs? Why would BarGetter.fetch_bar be called with not deterministically (randomly?) chosen object?

Maybe one of the other matchers from here https://relishapp.com/rspec/rspec-mocks/v/3-7/docs/setting-constraints/matching-arguments i.e

expect(BarGetter).to receive(:fetch_bar).with(instance_of(Foo))

would fit your specs better?

Greg
  • 5,862
  • 1
  • 25
  • 52
0

When the existing matchers do not cover your requirements, you can pass a block to the expectation and run expect on the arguments

expect(BarGetter).to receive(:fetch_bar) do |arg|
  expect([condition1, condition2, condition3]).to include(arg)
end
Maxim Krizhanovsky
  • 26,265
  • 5
  • 59
  • 89