如何测试使用specs2调用error()的方法?

时间:2012-06-22 04:45:55

标签: scala specs2

我想测试一个在其中调用error()的方法。

IntEmptyStack.top是我想用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")
}

这是我到目前为止所写的规格:

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]
    }
  }
}

错误发生在第13行"raise error when top called" in {。错误消息为value must is not a member of Nothing。我认为Scala将s.top推断为Nothing,而不是抽象类中定义的Int。在这种情况下,如何在没有任何错误的情况下编写测试?

感谢您对此问题的任何评论/更正。

示例参考:Scala By Example

1 个答案:

答案 0 :(得分:5)

这里的问题是scala(和Java)允许子类在重写方法中返回比超类更具体的类型。在这种情况下,您的方法IntEmptyStack.top的返回类型为NothingInt的子类型,因为Nothing位于类型层次结构。

a must throwA[X]的类型为a

时,您编写Nothing等代码所需的隐式转换显然不适用

更改IntEmptyStack中的声明,如下所示:

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

或者,当然,您可以允许逻辑的正确性被类型系统 验证。也就是说,不可能获得位于空堆栈顶部的元素:返回类型为Nothing!不需要进行任何测试。