Skip to content

Testing for URLs with rspec

I’ve become a big fan of rspec, and the idea of testing models, views and controllers independently of each other. View testing has for me tended to get short shrift, though; there’s not typically a lot of code in there, and who cares what it looks like, right? (kidding)I recently changed how authorization and authentication were handled on a project, though, so I really needed to make sure admin links only appeared for admins, etc. So, what I needed was a matcher for urls; does it have one in this case? Not in this other case? There’s not a url matcher built in to rspec, so I wrote one. Here it is, in case it helps you:

module ViewMatchers

A custom matcher to see if an expected url is included in the response. This one checks# the url itself, not the hyperlink text

class HaveLinkTo

def initialize(expected)

@expected = expected

end

def matches?(response)

result = false

@actual = response.body

@actual =~ /(<a\s+href="(http:\/)?(.?)#{expected}">\s((\n|.)+?)\s*<\/a>).?/

end

def failure_message

"expected #{expected.inspect}, got #{actual.inspect}"

end

def negative_failure_message

"expected #{@actual.inspect} not to include a url of #{@expected}"

end

private

attr_reader :expected

attr_reader :actual

end

A custom matcher to see if an expected url is included in the response. This one checks

the hyperlink text, not the url

class HaveLinkedText

def initialize(expected)

@expected = expected

end

def matches?(response)

@actual = response.body

@actual =~ /(<a\s+href="(http:\/)?(\/.+?)">\s((#{expected})+?)\s<\/a>).?/

end

def failure_message

"expected #{expected.inspect}, got #{actual.inspect}"

end

def negative_failure_message

"expected #{@actual.inspect} not to include a url of #{@expected}"

end

private

attr_reader :expected

attr_reader :actual

end

def have_link_to(expected)

HaveLinkTo.new(expected)

end

def have_linked_text(expected)

HaveLinkedText.new(expected)

end

end</a\s+href="(http:\></pre> Save that into view_matchers.rb in your /lib dir, and put this at the top of your spec_helper.rb: <pre> <code> config.include(ViewMatchers)

Then, in your view specs you can do things like:

response.should have_link_to(new_user_path)

response.should have_linked_text("New User")

Which is about 90% of the sort of testing I need to do with my views, so I hope that’s helpful to you.

Post a Comment

Your email is never published nor shared. Required fields are marked *
*
*