在使用scalamock的scala中将模拟对象用作隐式对象 [英] Using a mocked object as an implicit in scala using scalamock

查看:175
本文介绍了在使用scalamock的scala中将模拟对象用作隐式对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用具有各种具体派生特征的特性定义,并且将其隐式注入对象中,并在进行单元测试时模拟出系统的各个部分.问题在于,当类型的模拟版本用作隐式声明时,使用对象中的scala不会匹配它.

I am using a trait definition with various concrete derivatives and implicit to inject dependancies into objects and also to mock out parts of the system when unit testing. The problem is that when a mocked version of a type is used as an implicit declaration, it is not matched by scala in the consuming object.

这是我的设置的简化版.有没有一种方法可以使模拟使用 Test1 . Test2 可以正常工作,但难以维护,需要太多设置.

Here is a simplified version of my setup. Is there a way to make Test1 work using a mock. Test2 works fine but it hard to maintain and requires too much setup.

模型:

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 usage of component impl somewhere in system:

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也不与隐式类匹配:

Unit Test1, trying to mock out provider in order to isolate repository test. This does not work, the repository class does not match the implicit even though it is based on 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)
  }
}

此版本确实有效,但难以维护,并且需要更多代码:

This version does work but is hard to maintain and requires more code:

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模式?

Is there a way to use a mocked type as an injected implicit - or is there another scala-thonic a pattern I should use to solve this problem?

推荐答案

此代码已成功为我编译并运行

This code successfully compiles and runs for me

斯卡拉:2.10.4

scala: 2.10.4

scalaTest:2.1.0-RC2

scalaTest: 2.1.0-RC2

scalaMock:3.1.RC1

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)
  }
}

这篇关于在使用scalamock的scala中将模拟对象用作隐式对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆