Unsere Anwendung ist auf gebaut Spielen Sie 2,4 mit Scala 2.11 und Akka. Die verwendete Datenbank ist MySQL.Fehler bei Play 2.4 Tests: Der CacheManager wurde heruntergefahren. Es kann nicht mehr verwendet werden
Cache wird stark in unserer Anwendung verwendet. Wir verwenden Play standardmäßig EhCache für Caching.
Unser Beispielcode-Schnipsel:
import play.api.Play.current
import play.api.cache.Cache
case class Sample(var id: Option[String],
//.. other fields
)
class SampleTable(tag: Tag)
extends Table[Sample](tag, "SAMPLE") {
def id = column[Option[String]]("id", O.PrimaryKey)
// .. other field defs
}
object SampleDAO extends TableQuery(new SampleTable(_)) with SQLWrapper {
def get(id: String) : Future[Sample] = {
val cacheKey = // our code to generate a unique cache key
Cache.getOrElse[Future[[Sample]](cacheKey) {
db.run(this.filter(_.id === id).result.headOption)
}
}
}
Wir verwenden Spiele-eingebauten Specs2 zum Testen.
var id = "6879a389-aa3c-4074-9929-cca324c7a01f"
"Sample Application " should {
"Get a Sample" in new WithApplication {
val req = FakeRequest(GET, s"/v1/samples/$id")
val result = route(req).get
assertEquals(OK, status(result))
id = (contentAsJson(result).\("id")).get.toString().replaceAllLiterally("\"", "")
}
Aber während Komponententests begegnen wir oft die folgenden Fehler.
[error] 1) Error in custom provider, java.lang.IllegalStateException: The CacheManager has been shut down. It can no longer b
e used.
[error] at play.api.cache.EhCacheModule.play$api$cache$EhCacheModule$$bindCache$1(Cache.scala:181):
[error] Binding(interface net.sf.ehcache.Ehcache qualified with QualifierInstance(@play.cache.NamedCache(value=play)) to Prov
iderTarget([email protected])) (via modules: com.google.inject.util.Modules$OverrideModule -> play.ap
i.inject.guice.GuiceableModuleConversions$$anon$1)
[error] while locating net.sf.ehcache.Ehcache annotated with @play.cache.NamedCache(value=play)
[error] at play.api.cache.EhCacheModule.play$api$cache$EhCacheModule$$bindCache$1(Cache.scala:182):
[error] Binding(interface play.api.cache.CacheApi qualified with QualifierInstance(@play.cache.NamedCache(value=play)) to Pro
viderTarget([email protected])) (via modules: com.google.inject.util.Modules$OverrideModule -> play.
api.inject.guice.GuiceableModuleConversions$$anon$1)
[error] while locating play.api.cache.CacheApi annotated with @play.cache.NamedCache(value=play)
[error] while locating play.api.cache.CacheApi
[error]
[error] 1 error (InjectorImpl.java:1025)
[error] com.google.inject.internal.InjectorImpl$2.get(InjectorImpl.java:1025)
[error] com.google.inject.internal.InjectorImpl.getInstance(InjectorImpl.java:1051)
[error] play.api.inject.guice.GuiceInjector.instanceOf(GuiceInjectorBuilder.scala:321)
[error] play.api.inject.guice.GuiceInjector.instanceOf(GuiceInjectorBuilder.scala:316)
[error] play.api.Application$$anonfun$instanceCache$1.apply(Application.scala:234)
[error] play.api.Application$$anonfun$instanceCache$1.apply(Application.scala:234)
[error] play.utils.InlineCache.fresh(InlineCache.scala:69)
[error] play.utils.InlineCache.apply(InlineCache.scala:62)
[error] play.api.cache.Cache$.cacheApi(Cache.scala:63)
[error] play.api.cache.Cache$.getOrElse(Cache.scala:106
Wir freuen uns auf Hilfe entweder auf die obige Frage oder Möglichkeiten der Lösung eine Mock-Cache ausschließlich für die Prüfung zu implementieren.
Vielen Dank im Voraus.
Dieses Problem ist in der Regel durch zwei Play-Anwendungen irgendwie zugleich läuft mit (was aufgrund EHCache des globalen Singletons Natur verursacht Probleme, da wenn eine Anwendung heruntergefahren wird, die andere sie immer noch benutzt.) Unter Verwendung von 'WithApplication' _sollte_ eine neue App für jede Spezifikation starten und herunterfahren, aber ich habe festgestellt, dass bestimmte Plugins (oder besser, Module jetzt) kann Probleme verursachen, wenn sie den Lebenszyklus der App beeinflussen. Sie stellen nicht genügend Informationen bereit, um eine vollständige Diagnose zu stellen, aber versuchen Sie herauszufinden, wie zwei (gefälschte) Anwendungen gleichzeitig ausgeführt werden können. – Mikesname
Ja Mikesname .. sogar ich habe die gleiche dbt, dass, wenn jede Testspezifikation als eine einzige neue Anwendung läuft .. der Cache automatisch für jede Spezifikation starten und herunterfahren sollte.Aber wie du erwähntest, könnte die Singleton-Natur des Cache-Objekts im ehcachemodule das Problem sein. Wie ich anfing, Guice DI zu verwenden, um Cache-Instanz zur Laufzeit zu injizieren .. und einen separaten Fake Cache implementiert, wie von @Steve unten vorgeschlagen. Ich deaktivierte Standard EhCacheModule und aktivierte dieses gefälschte Zwischenspeichermodul für Testumgebung. Und meine Tests laufen jetzt gut :) – Bhavya