首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >玩!Scala2.5:测试类注入缓存会导致错误

玩!Scala2.5:测试类注入缓存会导致错误
EN

Stack Overflow用户
提问于 2016-09-12 15:26:40
回答 4查看 3.9K关注 0票数 8

我第一次使用游戏的缓存!斯卡拉2.5除了测试外,它工作得很好。

我的测试仍然通过,因为我不需要缓存,但是我得到了这个错误(还有很多人告诉我同样的事情):

代码语言:javascript
复制
Unable to provision, see the following errors:

1) Error in custom provider, play.api.cache.EhCacheExistsException: An EhCache instance with name 'play' already exists.

我理解这个错误,但是我没有成功地实现我自己版本的缓存API (来模拟它)。

我试着做播放邮件列表上告诉我的事情,但没有成功( Play!2.4有一些不同,因为模块是依赖注入的)。任何帮助都是欢迎的。

编辑:我所做的事情(它不会改变任何事情):

我的CacheApi版本(仅供测试):

代码语言:javascript
复制
class MyCacheApi extends CacheApi {
  lazy val cache = {
    val manager = CacheManager.getInstance()
    manager.addCacheIfAbsent("play")
    manager.getCache("play")
  }

  def set(key: String, value: Any, expiration: Duration = Duration.Inf) = {}

  def remove(key: String) = {}

  def getOrElse[A: ClassTag](key: String, expiration: Duration = Duration.Inf)(orElse: => A): A = {
    get[A](key).getOrElse {
      val value = orElse
      set(key, value, expiration)
      value
    }
  }

  def get[T: ClassTag](key: String): Option[T] = None
}

在我的测试中,我像这样使用它:

代码语言:javascript
复制
lazy val appBuilder = new GuiceApplicationBuilder()
    .in(Mode.Test)
    .overrides(bind[CacheApi].to[MyCacheApi])

lazy val injector = appBuilder.injector()
lazy val cache = new MyCacheApi
lazy val facebookAPI = new FacebookAPI(cache)

但是当我测试类FacebookAPI的函数时,测试通过了,但是由于名为“play”的EhCache实例已经存在,所以仍然有很多错误消息.

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2017-03-28 09:57:00

我终于找到了解决办法。

我添加了一个test.conf文件(在conf文件夹中):

代码语言:javascript
复制
play.cache.bindCaches = ["controller-cache", "document-cache"]

play.cache.createBoundCaches = false

为了使这个conf文件在测试中使用,我刚刚在我的build.sbt的设置部分中添加了以下行:

代码语言:javascript
复制
javaOptions in Test += "-Dconfig.resource=tests.conf"

如果你需要更多细节,请告诉我。

票数 5
EN

Stack Overflow用户

发布于 2018-08-03 07:11:23

在我的play(2.6.17)和scala (2.12.6) @GeReinhart的回答中,需要做一些小改动。

  • 注入注释
  • 如果过期是无限的,expiration.toSeconds会抛出非法的参数异常,所以有限的检查

-

代码语言:javascript
复制
import akka.Done
import javax.inject.Inject
import net.sf.ehcache.Element
import play.api.cache.AsyncCacheApi

import scala.concurrent.duration.Duration
import scala.concurrent.{ExecutionContext, Future}
import scala.reflect.ClassTag

class InMemoryCache @Inject()()(implicit ec: ExecutionContext) extends AsyncCacheApi {

  val cache = scala.collection.mutable.Map[String, Element]()

  def remove(key: String): Future[Done] = Future {
    cache -= key
    Done
  }

  def getOrElseUpdate[A: ClassTag](key: String, expiration: Duration)(orElse: => Future[A]): Future[A] = {
    get[A](key).flatMap {
      case Some(value) => Future.successful(value)
      case None        => orElse.flatMap(value => set(key, value, expiration).map(_ => value))
    }
  }

  def set(key: String, value: Any, expiration: Duration): Future[Done] = Future {
    val element = new Element(key, value)

    if (expiration.isFinite()) {
      element.setTimeToLive(expiration.toSeconds.toInt)
    } else {
      element.setEternal(true)
    }

    cache.put(key, element)
    Done
  }

  def get[T: ClassTag](key: String): Future[Option[T]] = Future {
    cache.get(key).map(_.getObjectValue).asInstanceOf[Option[T]]
  }

  def removeAll(): Future[Done] = Future {
    cache.clear()
    Done
  }

}

在下面需要导入的应用程序生成器中

代码语言:javascript
复制
import play.api.inject.bind
票数 2
EN

Stack Overflow用户

发布于 2018-10-05 16:53:05

如果有多个使用相同缓存的测试套件,则可以在每个测试套件的末尾显式关闭CacheManager并按顺序运行它们:

代码语言:javascript
复制
override def afterAll(): Unit = {
  CacheManager.getInstance().shutdown()
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39453838

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档