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

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.

comments powered by Disqus