La nostra applicazione è basata su Riproduci 2.4 con Scala 2.11 e Akka. Il database utilizzato è MySQL.Errore con Play 2.4 Test: CacheManager è stato chiuso. Non può più essere utilizzato
La cache viene utilizzata intensamente nella nostra applicazione. Usiamo EhCache predefinito per la memorizzazione nella cache.
Il nostro codice di esempio frammento di:
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)
}
}
}
Usiamo giochiamo integrato Specs2 per il test.
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("\"", "")
}
Ma mentre unit test abbiamo spesso incontrano l'errore sotto.
[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
Vi aspettiamo per aiuto su entrambi risolvere il problema sopra o modi per implementare una cache finto esclusivamente per il test.
Grazie in anticipo.
Questo problema è di solito a causa di avere due applicazioni Giocare in qualche modo in esecuzione allo stesso tempo (che a causa della natura Singleton globale di EHCache causa problemi, dal momento che quando un'applicazione si arresta, l'altro la userà ancora.) Usando 'WithApplication' _should_ avvia e chiude una nuova app per ogni specifica, ma ho trovato che alcuni plugin (o meglio, i moduli ora) può causare problemi se influiscono sul ciclo di vita dell'app. Non fornisci informazioni sufficienti per una diagnosi completa, ma prova a scoprire come potrebbero funzionare contemporaneamente due applicazioni (false). – Mikesname
Sì Mikesname .. anche io ho lo stesso dbt che quando ogni specifica di test viene eseguita come una singola nuova applicazione .. la cache dovrebbe automaticamente avviarsi e spegnersi per ogni specifica.Ma come hai menzionato la natura singleton dell'oggetto cache nell'ehcachemodule potrebbe essere il problema .. Qualsiasi modo in cui ho iniziato a usare Guice DI per iniettare l'istanza della cache in fase di esecuzione .. e implementato una cache falsa separata come suggerito da @Steve qui sotto. Ho disabilitato il default EhCacheModule e ho abilitato questo modulo di cache Fake per l'ambiente di test .. E ora i miei test stanno funzionando bene :) – Bhavya