【问题标题】:How can I test a method which calls error() with specs2?如何测试使用 specs2 调用 error() 的方法?
【发布时间】:2012-06-22 04:45:54
【问题描述】:

我想对其中调用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。在这种情况下,我怎样才能编写一个没有任何错误的测试?

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

示例参考:Scala By Example

【问题讨论】:

    标签: scala specs2


    【解决方案1】:

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

    显然,当a 的类型为Nothing 时,您编写a must throwA[X] 之类的代码所需的规范隐式转换不适用

    如下更改IntEmptyStack中的声明:

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

    当然,您也可以允许您的逻辑的正确性类型系统证明。也就是说,不可能获取位于空堆栈顶部的元素:返回类型为Nothing!无需测试。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-11-02
      • 2019-03-30
      • 2016-02-29
      • 2015-05-22
      • 2014-08-26
      • 1970-01-01
      • 1970-01-01
      • 2016-04-26
      相关资源
      最近更新 更多