私の最初の質問である質問には回答がありましたが、私が抱えている別の問題が明らかになりました。これがシナリオです。
サンプルコード (前の質問から拡張)
モデル:
case class User (first: String, last: String, enabled: Boolean)
コンポーネント定義:
trait DataProviderComponent {
def find[T: ClassTag](id: Int): Try[T]
def update[T](data: T): Try[T]
}
具体的なコンポーネントの実装の 1 つ (更新された実装):
class DbProvider extends DataProviderComponent {
override def find[T: ClassTag](id: Int): Try[T] = {
Try {
val gson = new Gson()
val testJson = """{"first": "doe", "last": "jane", "enabled": false}"""
gson.fromJson(testJson, implicitly[ClassTag[T]].runtimeClass).asInstanceOf[T]
}
}
override def update[T](data: T): Try[T] = ???
}
システム内のどこかでコンポーネント impl が暗黙的に使用されています:
implicit val provider = new DbProvider()
class UserRepsitory(implicit provider: DataProviderComponent) {
def userEnabled(id: Int): Boolean = {
val user = provider.find[User](id)
user.isSuccess && user.get.enabled
}
}
単体テスト 1、リポジトリ テストを分離するためにプロバイダーをモックアウトしようとしています。これは機能しません。テストの実行時に次の execption がスローされます。ClassTag を使用しない別のサンプルを作成すると、正常に動作するため、ClassTag の使用が原因であると思われます。
org.scalamock.MockFunction2 は org.scalamock.MockFunction1 にキャストできません java.lang.ClassCastException: org.scalamock.MockFunction2 は org.scalamock.MockFunction1 にキャストできません
class UserRepository$Test1 extends FunSuite with Matchers with MockFactory {
test("invalid data request should return false") {
implicit val mockProvider: DataProviderComponent = mock[DataProviderComponent]
(mockProvider.find[User] _).expects(13).returns(Failure[User](new Exception("Failed!")))
val repo = new UserRepsitory()
repo.userEnabled(13) should be (false)
}
}
Unit Test2 は機能しますが、保守が難しく、より多くのコードが必要です。
class UserRepository$Test2 extends FunSuite with Matchers with MockFactory {
test("invalid data request should return false") {
class FakeProvider extends DataProviderComponent {
override def find[T:ClassTag](id: Int): Try[T] = Failure[T](new Exception("Failed!"))
override def update[T](data: T): Try[T] = ???
}
implicit val provider = new FakeProvider()
val repo = new UserRepsitory()
repo.userEnabled(13) should be (false)
}
}
Unit Test3 は機能しますが、ClassTag の実装をテストするためだけに使用されます。
class UserRepository$Test3 extends FunSuite with Matchers with MockFactory {
test("prove sut works") {
implicit val provider = new DbProvider()
val repo = new UserRepsitory()
val user = repo.userEnabled(13)
println(user.toString)
}
}
ClassTag を間違って使用していますか、それともモックが適切にモックできませんか?