rspec-style-guide icon indicating copy to clipboard operation
rspec-style-guide copied to clipboard

Encourage to use local matchers

Open pirj opened this issue 6 years ago • 2 comments
trafficstars

E.g.

  matcher :be_just_like do |expected|
    match {|actual| actual == expected}
  end

Related docs: https://relishapp.com/rspec/rspec-expectations/v/3-8/docs/custom-matchers/define-a-custom-matcher#scoped-in-a-module https://relishapp.com/rspec/rspec-expectations/v/3-8/docs/custom-matchers/define-a-custom-matcher#scoped-in-an-example-group

Caveats

I personally find it very confusing that those matchers don't have access to group variables, as opposed to ad-hoc methods:

def send_message
  have_attributes(channel: channel, text: text)
end

let(:channel) { '#announcements' }
let(:text) { 'Hello, world' }

it { is_expected.to send_message }

With a matcher:

let(:channel) { '#announcements' }
let(:text) { 'Hello, world' }

# works
matcher :send_message do |channel, text|
  values_match? actual, have_attributes(channel: channel, text: text)
end

it { is_expected.to send_message(channel, text) }

# fails with
#     undefined local variable or method `channel' for #<Class:#<RSpec::Matchers::DSL::Matcher:0x00007fb334216058>> 

matcher :send_message do
  values_match? actual, have_attributes(channel: channel, text: text)
end

it { is_expected.to send_message }

pirj avatar Nov 23 '18 10:11 pirj

What does “local” mean in this context? Would you recommend defining one-off matchers for a single example group?

bquorning avatar Nov 23 '18 20:11 bquorning

Yep, local to an example group, so that it's not accessible in the other example groups.

It depends on the number of examples in the group and the complexity of the match condition. Sometimes two examples are enough to start thinking of extracting them. Shared examples might be an option, but they create additional group, and with expensive setup this might not be desirable.

The matcher defined does not necessarily have to be defined in the example group itself, it may be in the module, and be included in the example group, or several example groups even spread over different spec files.

pirj avatar Nov 26 '18 09:11 pirj