Assert_tag With Two Siblings In Rails
I was recently dealing with a tricky problem while writing some rails tests.
I was writing assert_tags against xml returned by a rails web service in order to test that the xml contained specific values.
Here is a sample of the XML:
<elements> <element> <name>rod</name> <surname>hilton</surname> <value>123</value> </element> <element> <name>rod</name> <surname>smith</surname> <value>456</value> </element> <element> <name>granny</name> <surname>smith</surname> <value>789</value> </element> </elements>
I want to write three assertions. If I write this in my test, it will work as expected:
assert_tag :tag=>"value", :content=>"789", :sibling=>{:tag=>"name", :content=>"granny"}
Basically what I'm doing is looking for a value element with the content of 789, and it has to have a sibling of a name element with the content "granny", which assures it will select the last "element" for the value.
The problem is, how do I write a test for the first xml element? If I look for a sibling with name "rod", it's possible that I'd select the second element. If look for a sibling with the surname "smith", it's possible that I'd select granny again. I need to be able to select the tag with TWO siblings.
The documentation is not straightforward about how to do this, but I figured out a method that works.
Essentially, the :sibling hash element takes the same kind of hash that assert_tag takes. Meaning, you can pass anything into :sibling that you would pass to assert_tag to begin with - including another sibling!
assert_tag :tag=>"value", :content=>"123", :sibling=>{ :tag=>"name", :content=>"rod", :sibling=>{ :tag=>"surname", :content=>"hilton" } }
Pretty insane, but I wasn't able to figure out a better way. I was hoping to pass an array of hashes to :sibling, but that didn't work as I had hoped.
If anyone has a better way than this, feel free to leave a comment. Otherwise, this seems to be a relatively readable way of selecting tags with 2 (or more) siblings in assertions.




















Tamer Salama:
I believe you can use the :before, and :after hashes to test a certain number of occurrences.
assert_tag :tag=>”element”,
:before => {
:tag => “element”,
:before => {
:tag => “element”
}
}
would assert you’re returning 3 element tags
I know, it’s ugly.
Thanks for the pointer.
10 June 2008, 4:46 pm