Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Encourage to use local matchers #62

Open
pirj opened this issue Nov 23, 2018 · 2 comments
Open

Encourage to use local matchers #62

pirj opened this issue Nov 23, 2018 · 2 comments

Comments

@pirj
Copy link
Member

pirj commented Nov 23, 2018

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 }
@bquorning
Copy link

bquorning commented Nov 23, 2018

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

@pirj
Copy link
Member Author

pirj commented Nov 26, 2018

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants