scala objectのMock その2
どうもJMockitではscalaのobjectをモック化できないようなので、scalaベースのscalamockを試してみる。scalamockはsbt, scalatestの使用を前提としているため、sbtでプロジェクトを作る。プロジェクトの構成がsbtの構成になってしまうので、これもちょっと困る。環境構築に必要なファイルは以下
$PROJECT_ROOT/build.sbt
name := "test.sbt"version := "1.0"
scalaVersion := "2.9.2"
libraryDependencies ++= Seq(
"org.scalatest" %% "scalatest" % "1.8" % "test",
"org.scalamock" %% "scalamock-scalatest-support" % "2.3",
"junit" % "junit" % "latest.integration" % "test",
"commons-logging" % "commons-logging" % "1.1.1"
)
$PROJECT_ROOT/project/Build.scala
import sbt._
import Keys._
import ScalaMockPlugin._object MyProject extends Build {
override lazy val settings = super.settings ++ Seq(
organization := "",
version := "1.0",
scalaVersion := "2.9.2",
libraryDependencies += "org.scalamock" %% "scalamock-scalatest-support" % "2.4",
autoCompilerPlugins := true,
addCompilerPlugin("org.scalamock" %% "scalamock-compiler-plugin" % "2.4")
)
lazy val myproject = Project("MyProject", file(".")) settings(generateMocksSettings: _*) configs(Mock)
$PROJECT_ROOT/project/plugins.sbt
addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "2.1.1")
$PROJECT_ROOT/project/project/PluginDef.scala
import sbt._
object PluginDef extends Build {
override lazy val projects = Seq(root)
lazy val root = Project("plugins", file(".")) dependsOn(scalamockPlugin)
lazy val scalamockPlugin = uri("git://github.com/paulbutcher/scalamock-sbt-plugin")
}
これで環境はできた。sbt elipseなどしてeclipseでもインポートできるようにする。テストのターゲットクラスは以下
package test2class Boo
object Boo {
def foo = {
println("Boo#foo called")
true
}
}
$PROJECT_ROOT/src/generate-mocks/scala/GenerateMocks.scala
import org.scalamock.annotation.mockObjectclass GenerateMocks {
@mockObject(Boo) class BooMock
}
として、sbt generate-mocksする。するとモックオブジェクトができあがる。次にテストコード
import org.scalatest.FunSuite
import org.scalamock.scalatest.MockFactory
import org.scalamock.generated.GeneratedMockFactory
import org.scalamock.scalatest.MockFactoryclass BooTest {
test("Boo#foo 通常動作") {
assert(Boo.foo)
}test("Boo#foo モックを使って結果を変える") {
val boo = mockObject(Boo)
boo.expects.foo() returning ({println("BooMock#foo called");false})assert(! Boo.foo)
}}
このとき、eclipseだと、org.scalamock.generated.GeneratedMockFactoryが見えなくてエラーになってしまう。ビルドパスのソースフォルダに、target/scala-2.9.2/src_managed/test/scalaを追加すると解決。sbt eclipseがやってくれるといいがやってくれない。sbt eclipseを実行するとこの設定はなくなってしまうので要注意。
ここまでできたらsbt testとすれば
Boo#foo called
BooMock#foo called
[info] BooTest:
[info] - Boo#foo 通常動作
[info] - Boo#foo モックを使って結果を変える
[info] Passed: : Total 4, Failed 0, Errors 0, Passed 4, Skipped 0
[success] Total time: 2 s, completed 2013/09/06 18:51:24
となってモックが呼ばれていることがわかる。