Rspec test for converting a hash to a URL string

Hi all, I’ve written an expectation for a method that converts a hash
into a url string of name/value pairs. The problem is that the hash is
not traversed in the same order as it is defined so I can not work out
how to test for the correct returned string. The operation of the code
does not require and specific order so I am not going to add a
specific order to my method.


def mappings_data
:shell => true,
:ftp => 10,
:sql => 11,
:email => 12,
:subdomains => 13,
:parkeddomains => 14,
:addondomains => 15,
:transfer => 16

it “should map arguments to a url” do


def map_args_to_url(args={})
‘?’ + { |k,v| “%s=%s” % [URI.encode(k.to_s),
URI.encode(v.to_s)] }.join(’&’) unless args.blank?

string that is returned


On Mon, Apr 14, 2008 at 6:58 PM, Jamie D [email protected]


string that is returned


rspec-users mailing list
[email protected]

You can use the CGI library to parse the query string, and verify that
the hashes are equal.

params = {:foo => true, :bar => 12}
params_as_strings = {}
params.each_key {|key| params_as_strings[key.to_s] = params[key].to_s }
query_string = map_args_to_url params
CGI.parse(query_string.delete("?")).should == params_as_strings

(completely untested, so you’ll have to mess with it I’m sure)

That’s a bit ugly and verbose, so it may be a good candidate for a
custom matcher

query_string.should equal_query_string("?foo=true&bar=12")

The matcher would call CGI.parse on the actual and expected strings
and verify that they are equal.

Another thing that jumps out at me is that there may be a chance to
build a QueryParams abstraction. So instead of the above expectation,
you might do

query_params.should == => true, :bar => 12)

(you would still have to write a spec verifying the QueryParams#to_s
hash->string conversion of course)

If all you’re doing at this point is building that string, then a
QueryParams object is probably overkill. But I would be ready to move
to it as soon as I started to do any more logic with the query string,
such as asserting that it contains a certain key-value pair.

Like I said at the beginning, this is probably a good situation for a
custom expectation matcher to hide some of the messy details. Just
keep in mind that the thresholds for creating a custom matcher and
creating a new object are not that far apart, and creating a new
object is generally way more valuable.

(that was almost certainly a lot longer than you wanted, sorry. I’ve
just been sick the last couple days and needed to scratch my
list-writing itch :slight_smile:


Thanks Pat,

I wrote my first custom matcher and its all working now.


This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs