Reputation: 9010
I have been testing my code with Specs2 for some time now and in my test I wanted to ensure that two objects of some type compare correctly:
"compare based on carrier value" in {
val b0 = new BitField32(343948)
val b0prim = new BitField32(343948)
val b1 = new BitField32(112)
b0prim should be equalTo(b0)
b1 should not be equalTo(b0)
}
When this test was executed, I got an error
[error] x compare based on carrier value
[error] 'core.BitField32@17805bd5' is not equal to 'core.BitField32@6c0d0900' (BitField32Spec.scala:34)
[error] Expected: ...ld32@[6c0d0900]
[error] Actual: ...ld32@[17805bd5]
Which seemed reasonable, since my class didn't have any methods for comparison. So I tried a couple of things that came to mind: implementing Ordered
and providing a variety of comparison methods:
/**
* mutable 32bit Bitfield
*/
class BitField32(var carrier: Int) extends Ordered[BitField32]{
override def equals(that: Any) = true
def canEqual(that: Any) = true
def compare(that: BitField32) = this.carrier - that.carrier
def ===(that: BitField32) = this.carrier == that.carrier
def ==(that: BitField32) = this.carrier == that.carrier
//(...)
}
But I still keep getting the same error. I tried to read specs2 sources to see how the equalTo matcher works, but I wasn't any wiser afterwards.
Any idea how I have to modify my class for the equality to be picked up by (stock) specs2 matchers?
BitField32 isn't a case class by design - I want it to be mutable.
Upvotes: 1
Views: 1408
Reputation: 9010
I actually misread the error message after adding the comparison methods: it was saying that compared objects were equal, even though they shouldn't have been. The comparison used by specs2 was in place and it was always returning true - the equals
method. Here is the fixed code:
class BitField32(var carrier: Int){
override def equals(that: Any) = that match {
case bf: BitField32 => this == bf
case _ => false
}
def ==(that: BitField32) = this.carrier == that.carrier
}
Upvotes: 2