Search code examples
scalaspecs2

Scala Specs2 Matchers with "aka" doesn't work


Scala Specs2 matcher that looks like this (for example):

  def haveSizeOf(size: Int): Matcher[ProductElement] = { 
    productElement: ProductElement =>
    val sizeOfproductElement = productElement.size
    sizeOfproductElement aka "size of product element"
  } ^^ beEqualTo(size)

And it's execution in the code:

updatedProductElement must haveSizeOf(1)

Throws error:

java.lang.Exception: 'org.specs2.matcher.ThrownExpectations$$anon$1@6a3b7968'

is not equal to

'1'

What should i have done differently?

Edit: If aka removed, test passing successfully:

   def haveSizeOf(size: Int): Matcher[ProductElement] = { 
        productElement: ProductElement =>
        productElement.size
      } ^^ beEqualTo(size)

Solution

  • beEqualTo() compare a value (like size) to Any value, including a org.specs2.matcher.ThrownExpectation which is the value you build with aka. The correct way to build the haveSizeOf matcher is

    def haveSizeOf(size: Int): Matcher[ProductElement] = { 
      productElement: ProductElement =>
      val sizeOfproductElement = productElement.size
      beEqualTo(size).apply(sizeOfproductElement aka "size of product element")
    }
    

    Each Matcher[T] has an apply method which accepts values that are of type Expectation[T] (basically an expectation is a value of type T plus an optional description which you build with aka).

    Another way to build the same matcher, without reusing beEqualTo is

    def haveSizeOf(size: Int): Matcher[ProductElement] = { 
      productElement: ProductElement =>
      (productElement.size == size,
       s"the size of product element ${productElement.size} is not $size")
    }