Rod Hilton's rants about software development, technology, and sometimes Star Wars

# 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.