测试是否在scala中的给定范围内调用函数

时间:2013-10-06 11:05:19

标签: unit-testing scala junit

我正在跟踪课程中的scala课程,并且我被要求在上一次练习中实施设置操作。我失败的测试之一被称为

  

存在应该以forall

来实现

存在和forall签名都是:

type Set = Int => Boolean

def forall(s: Set, p: Int => Boolean): Boolean = {}
def exists(s: Set, p: Int => Boolean): Boolean = {

   /*should eventually call forall */
}

我不是要求实现,而是如何在scala中执行这样的单元测试

2 个答案:

答案 0 :(得分:3)

我可以想到三种方法:

1)模拟forall抛出特定异常,然后调用exists,看看是否抛出该异常。

2)检测代码并调用exists,然后进行测试,看看是否调用了forall

3)使用scala宏,它分析exists的AST并递归检查它是否调用forall

答案 1 :(得分:1)

使用模拟对象可以轻松完成。我在我的Java项目中使用Mockito,它也非常适用于Scala,特别是与Scalatest一起使用。

将此代码添加到project_dir/build.sbt

scalaVersion := "2.10.2"

libraryDependencies ++= Seq(
  "org.scalatest" %% "scalatest" % "2.0.M8",
  "org.mockito" % "mockito-core" % "1.9.5"
)

然后将此代码添加到project_dir/src/main/test/test.scala

import org.scalatest.{FlatSpec,ShouldMatchers}
import org.scalatest.mock.MockitoSugar

package object test {
  type Set = Int => Boolean
}

package test {
  class Foraller {
    def forall(s: Set, p: Int => Boolean): Boolean = ???
  }

  class Exister(foraller: Foraller) {
    def exists(s: Set, p: Int => Boolean): Boolean = ???  // Fails
    // def exists(s: Set, p: Int => Boolean): Boolean = foraller.forall(s, p)  // Passes
  }

  class Test extends FlatSpec with ShouldMatchers with MockitoSugar {
    "Exister" should "use Foraller in its exists method" in {

      val foraller = mock[Foraller]

      val exister = new Exister(foraller)

      val set: Set = _ == 1
      val pred: Int => Boolean = _ > 0

      exister.exists(set, pred)

      import org.mockito.Mockito._

      verify(foraller).forall(set, pred)
    }
  }
}

然后在sbt test中调用project_dir命令。你应该看到测试失败了。切换对Exister类中的行的注释,然后重试。

这里我们为提供forall方法的类创建模拟对象,我们在提供exists方法的类中使用此对象。 Mockito允许验证某个模拟对象上的某个方法是否被调用,这就是在这里工作的。