Reputation: 906
I'm trying to compare tuples containing arrays in Scala as part of some tests and running into a problem where it seems to compare the array objects rather than the contents.
Comparing arrays themselves works fine; this passes:
assertResult(Array[Byte](0.toByte, 2.toByte))(Array[Byte](0.toByte, 2.toByte))
However, when I put the array into a tuple, paired with a long, I get an exception
This is the test code:
assertResult((12345678L, Array[Byte](0.toByte, 2.toByte)))((12345678L, Array[Byte](0.toByte, 2.toByte)))
and the exception I get is:
org.scalatest.exceptions.TestFailedException: Expected (12345678,[B@2473d930), but got (12345678,[B@35047d03)
From the way it prints out the memory location of the arrays, it makes me think it's comparing the object references rather than deep comparing each object in the array.
Is this expected in Scala, or am I doing something wrong here? Thanks for reading.
Upvotes: 1
Views: 1291
Reputation: 61885
That is correct, per Java's array equality (or lack of) behavior.
As seen in the message ([B@2473d930
) the Scala Array type is a fancy skin for a Java-array; but it can't change how a Java array instance actually works.
The most straight forward solution is probably to use a collection type that properly implements ==
(aka Object.equals
).
Tuple1(Array(1)) == Tuple1(Array(1)) // false
Tuple1(List(1)) == Tuple1(List(1)) // true
(See m-z's answer for why the non-nested case works.)
Upvotes: 2
Reputation: 55569
It will work if you call deep
on the Array
s:
assertResult((12345678L, Array[Byte](0.toByte, 2.toByte).deep))((12345678L, Array[Byte](0.toByte, 2.toByte).deep))
This actually just converts the Array
to an IndexedSeq
so it can do the equals
comparison (instead of the default reference comparison on Array
). It seems as though assertResult
does this for you if the top level comparison is an Array
, but not if the Array
is nested within another object. This is why the first example works, but the second does not.
Given that, it's probably very inconvenient to have to do this, and you might consider using a different collection type other than Array
.
Upvotes: 6