使用scalamock在scala中将模拟对象作为隐式对象使用

使用scalamock在scala中将模拟对象作为隐式对象使用,scala,unit-testing,mocking,scalatest,scalamock,Scala,Unit Testing,Mocking,Scalatest,Scalamock,我使用了一个带有各种具体派生和隐式的特征定义,将依赖注入到对象中,并在单元测试时模拟系统的各个部分。问题在于,当类型的模拟版本用作隐式声明时,消费对象中的scala不匹配该类型 这是我的设置的简化版本。有没有一种方法可以让Test1使用mock工作。Test2工作正常,但很难维护,并且需要太多的设置 模型: case class User (first: String, last: String, enabled: Boolean) 组件定义: trait DataProviderCompon

我使用了一个带有各种具体派生和隐式的特征定义,将依赖注入到对象中,并在单元测试时模拟系统的各个部分。问题在于,当类型的模拟版本用作隐式声明时,消费对象中的scala不匹配该类型

这是我的设置的简化版本。有没有一种方法可以让Test1使用mock工作。Test2工作正常,但很难维护,并且需要太多的设置

模型:

case class User (first: String, last: String, enabled: Boolean)
组件定义:

trait DataProviderComponent {
  def find[T](id: Int): Try[T]
  def update[T](data: T): Try[T]
}
具体组件实现之一:

class DbProvider extends DataProviderComponent {
  override def find[T](id: Int): Try[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
  }
}
单元Test1,尝试模拟提供程序以隔离存储库测试。这不起作用,存储库类与隐式类不匹配,即使它基于DataProviderComponent:

class UserRepository$Test1 extends FunSuite with Matchers with MockFactory {
  test("invalid data request should return false") {
    implicit val  mockProvider = mock[DataProviderComponent]
    (mockProvider.find[User] _).expects(13).returns(Failure[User](new Exception("Failed!")))

    val repo = new UserRepsitory()
    repo.userEnabled(13) should be (false)
  }
}
此版本可以工作,但很难维护,需要更多代码:

class UserRepository$Test2 extends FunSuite with Matchers with MockFactory {
  test("invalid data request should return false") {
    class FakeProvider extends DataProviderComponent {
      override def find[T](id: Int): Try[T] = ???
      override def update[T](data: T): Try[T] = Failure[T](new Exception("Failed!"))
    }

    implicit val provider = new FakeProvider()
    val repo = new UserRepsitory()
    repo.userEnabled(13) should be (false)
  }
}

有没有一种方法可以使用模拟类型作为注入隐式?或者有没有另一种scala thonic模式可以用来解决这个问题?

这段代码为我成功编译并运行

scala:2.10.4

缩放测试:2.1.0-RC2

scalaMock:3.1.RC1

import org.scalamock.scalatest.MockFactory
import org.scalatest.{FunSuite, Matchers}

import scala.util.{Failure, Try}

case class User(first: String, last: String, enabled: Boolean)

trait DataProviderComponent {
  def find[T](id: Int): Try[T]

  def update[T](data: T): Try[T]
}

class DbProvider extends DataProviderComponent {
  override def find[T](id: Int): Try[T] = {
    ???
  }

  override def update[T](data: T): Try[T] = {
    ???
  }
}

class UserRepository(implicit provider: DataProviderComponent) {
  def userEnabled(id: Int): Boolean = {
    val user = provider.find[User](id)
    user.isSuccess && user.get.enabled
  }
}

class UserRepositoryTest 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 UserRepository()
    repo.userEnabled(13) should be(false)
  }
}