Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Minitest assertion failing on inspect

Whenever I try to assert_equal two objects, I always get errors like this:

   No visible difference in the User#inspect output.
   You should look at the implementation of #== on User or its members.

It's happened with Time and Array as well. Minitest docs don't really say much on this either.

I'm using Ruby 2.0.0, but I was using 2.2.0 and the same happened. Using latest minitest as well.

Also, I'm running Ubuntu 14.10.

like image 634
Fabian Silva Avatar asked Feb 24 '15 13:02

Fabian Silva


2 Answers

About the message

This message, which kinda isn't an error, is shown when the assertion fails, but MiniTest fails to find a difference between the objects.

Check out this method.

diff runs #inspect on the two objects and runs a diff tool on that. If there is no diff, this message is shown.

In principle, you'd want two objects which aren't equal to have different output when inspected. This isn't written in stone though, and some classes in the ruby standard libraries don't fullfil this property, like Time. When it comes to your own classes, maybe you've written a custom #inspect method?

Regarding Time, inspect only shows seconds, not fractions, but equality looks at fractions, so two time objects may not be equal but still look the same when inspected.

Regarding Array, if objects included in it can be not equal but look the same when inspected, this will cause the message to be displayed.

If you get this message even though the inspect outputs are different, something is wrong with the diff tool. MiniTest tries to do some educated guesses about which diff tool to use. You can inspect the chosen diff tool by printing MiniTest::Assertions.diff.

On object equality

If the real issue is that your objects aren't equal when you expect them to be, you should look at how the == method is defined in the respective classes. The default implementation looks at the object ids given to each object when instantiated, which is probably not what you want if for example dealing with objects that represent database rows.

like image 159
Jesper Avatar answered Sep 17 '22 18:09

Jesper


Maybe the 2 objects' encoding instances are different. Use encoding and force_encoding to check :

puts obj1.encoding
puts obj2.encoding

Here is an example out put:

ISO-8859-1
ASCII-8BIT

In this case obj1's encoding instance is ISO-8859-1 and obj2's encoding instance is ASCII-8BIT. Then to convert obj1's encoding instance to ASCII-8BIT with force_encoding:

assert_equal(obj1.force_encoding(Encoding::ASCII_8BIT), obj2)

For more detail please check https://ruby-doc.org/core-2.2.0/Encoding.html

like image 36
Protocol Avatar answered Sep 19 '22 18:09

Protocol