■ はじめに
https://dk521123.hatenablog.com/entry/2023/03/31/002830
で、Java由来の Mockito を触ったが 今回は、ScalaTest + ScalaMock を触ってみる。
目次
【1】ScalaMock 【2】インストール 【3】使用上の注意 1)final / private メソッド・クラスはサポートされていない 【4】サンプル 例1:Hello world 例2:スタブ
【1】ScalaMock
* PureのScala製のMockツール * コンパイラプラグインでモックのソースコードを 自動生成するという手法を採用 => シングルトーンや final クラスのモックも作成可能
https://scalamock.org/
https://github.com/paulbutcher/ScalaMock
【2】インストール
https://scalamock.org/quick-start/
https://scalamock.org/user-guide/installation/
libraryDependencies ++= Seq( // ★注目 "org.scalamock" %% "scalamock" % "5.1.0" % Test, "org.scalatest" %% "scalatest" % "3.2.18" % Test )
【3】使用上の注意
1)final / private メソッド・クラスはサポートされていない
https://scalamock.org/user-guide/faq/
Can I mock final / private methods or classes? This is not supported, as mocks generated with macros are implemented as subclasses of the type to mock. So private and final methods cannot be overridden. You may want to try using an adapter or façade in your code to make it testable. It is better to test against a trait/interface instead of a concrete implementation. ... There are libraries that support this kind of mocking, such as PowerMock.
自分用メモ
LocalDate/LocalDateTime/System.currentTimeMillis() など を mock しようとしたが、 これらは、final なので、これじゃー使えない、、、
【4】サンプル
https://scalamock.org/quick-start/
Greetings.scala
object Greetings { trait Formatter { def format(s: String): String } object EnglishFormatter extends Formatter { def format(s: String): String = s"Hello $s!!" } def sayHello(name: String, formatter: Formatter): Unit = { println(formatter.format(name)) } }
例1:Hello world
GreetingsTest.scala
import org.scalatest.matchers.should import org.scalamock.scalatest.MockFactory class GreetingsTest extends AnyFunSuite with should.Matchers with MockFactory { test("Hello World Test") { val mockFormatter = mock[Formatter] (mockFormatter.format _).expects("Mike").returning("Hello Mike!!").once() Greetings.sayHello("Mike", mockFormatter) } }
例2:スタブ
import Greetings.Formatter import org.scalatest.funsuite.AnyFunSuite import org.scalatest.matchers.should import org.scalamock.scalatest.MockFactory class GreetingsTest extends AnyFunSuite with should.Matchers with MockFactory { test("Hello World Test") { // ★スタブ val mockFormatter = stub[Formatter] val bond = "Mr Bond" (mockFormatter.format _).when(bond).returns("Ah, Mr Bond. I've been expecting you") Greetings.sayHello(bond, mockFormatter) (mockFormatter.format _).verify(bond).once() } }
関連記事
Scala ~ テスティングフレームワーク ~
https://dk521123.hatenablog.com/entry/2024/06/07/183708
ScalaTest ~ 入門編 ~
https://dk521123.hatenablog.com/entry/2023/03/27/001306
ScalaTest ~ 基本編 ~
https://dk521123.hatenablog.com/entry/2023/03/28/003906
ScalaTest ~ with Mockito ~
https://dk521123.hatenablog.com/entry/2023/03/31/002830
ScalaTest ~ with ScalaCheck ~
https://dk521123.hatenablog.com/entry/2023/03/29/000014
ScalaTest ~ with Coverage ~
https://dk521123.hatenablog.com/entry/2023/08/07/222945
Scala ~ 環境構築編 ~
https://dk521123.hatenablog.com/entry/2023/03/10/193805
Scala ~ 入門編 ~
https://dk521123.hatenablog.com/entry/2023/03/12/184331
PowerMock ~ 入門編 ~
https://dk521123.hatenablog.com/entry/2018/04/09/224904