In be_created, I check for the status code to be 201 and a location of
the
new resource. In have_created_resource, i also pass in the resource that
was
created and verify it exists (non nil check) as well as that it passes
the
be_created criteria.
Github commit =>
I am getting an error saying be_created not found. Obviously, be_created
is
not in scope but if I fix it and include the required module it fails
for
be_nil not found.
I am finding this way of reusing the matchers not correct.
Is there a standard way of re-using matchers inside matchers ? Have
anybody
tried it out ?
Regards,
Amiruddin N.,
Bangalore, 560008, KA
India
Regarding DRY: while it is a very important principle, it is not the
only principle. The matches? method in have_created_resource exhibits
the Long Method and Feature Envy code smells, and violates the Tell,
Don’t Ask principle. Using be_created the way it’s being used is
operating with lower level details of the matcher framework, letting
those abstractions leak up to the matcher. I’d just write it like this
(using the matcher DSL):
RSpec::Matchers.define :have_created_resource do |resource, location|
match do |response|
response.code == “201” && resource
end
failure_message_for_should do |response|
<<-MESSAGE
expected to have created resource, but got:
response code: #{response.code}
resource: #{resource}
MESSAGE
end
end
Now each method does one thing. The match method does what it’s
supposed to: deciding whether or not to match. The
failure_message_for_should does what it’s supposed to: create a
failure message. The failure message is better aligned with the
matcher, and it’s always the same format regardless of why it failed.
There’s also no dependency between the matchers now, so they are free
to change independently.
HTH,
David
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.