This is reasonably standard stuff - when assertion_equal failed it printed out the expected and provided data. The problem in my case was that the hashes have about 50 elements, and I only want the difference to be shown in the test output.
I knocked up this function to solve the problem, and included it in my test class:
def assert_hashes_equal(expected, actual, message=nil)
full_message = build_message(message, "Hashes were not equal, diff was:\n.\n", expected.diff(actual))
assert_block(full_message) { expected == actual }
end
So now I get this:
Hashes were not equal, diff was:
<{:plays_in_category=>"2", :dynamic_end=>"MFT", :percent_back=>"100w"}>.
Note that Hash.diff is part of Rails.
Here is what the output looks like in practice:
1) Failure:
test: SelectorImporterTest Concert Selector Parse Song 0 XML should Hashes should be equal. (SelectorImporterTest)
[/test/unit/selector_importer_test.rb:500:in `assert_hashes_equal'
/test/unit/selector_importer_test.rb:368:in `__bind_1271217771_635209'
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/context.rb:253:in `call'
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/context.rb:253:in `test: SelectorImporterTest Concert Selector Parse Song 0 XML should Hashes should be equal. ']:
Hashes were not equal, diff was:
<{:mood=>"3"}>.