Question

I'd like to make a test for a method which calls error() in it.

IntEmptyStack.top is what I want to test with specs2:

abstract class IntStack {
  def push(x: Int): IntStack = new IntNonEmptyStack(x, this)
  def isEmpty: Boolean
  def top: Int
  def pop: IntStack
}
class IntEmptyStack extends IntStack {
  def isEmpty = true
  def top = error("EmptyStack.top")
  def pop = error("EmptyStack.pop")
}

And here's the specs I wrote so far:

import org.junit.runner.RunWith
import org.specs2.runner.JUnitRunner
import org.specs2.mutable.Specification

@RunWith(classOf[JUnitRunner])
class IntStackSpec extends Specification {

  "IntEmptyStack" should {
    val s = new IntEmptyStack
    "be empty" in {
      s.isEmpty must equalTo(true)
    }
    "raise error when top called" in {
      s.top must throwA[RuntimeException]
    }
  }
}

The error occurs in line 13, "raise error when top called" in {. The error message is value must is not a member of Nothing. I think Scala infers s.top as Nothing, not an Int as defined in the abstract class. In this case, how can I write a test without any errors?

Thanks for any comments/corrections to this question.

Example Reference: Scala By Example

Was it helpful?

Solution

The problem here is that scala (and Java) allow subclasses to return more-specific types than superclasses in overridden methods. In this case, your method IntEmptyStack.top's return-type is Nothing (which is a sub-type of Int because Nothing is at the bottom of the type hierarchy.

Evidently spec's implicit conversions necessary for you to write code like a must throwA[X] do not apply when the type of a is Nothing

Change your declarations in IntEmptyStackas follows:

def top: Int = error("EmptyStack.top")
def pop: Int = error("EmptyStack.pop")

Alternatively, of course, you could allow the fact that the correctness of your logic is being proven by the type system. That is, it is not possible to get an element which is at the top of an empty stack: the return type is Nothing! No tests are necessary.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top