nietaki
nietaki

Reputation: 9010

Specs2 - equality testing in scala

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

Answers (1)

nietaki
nietaki

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

Related Questions