迁移到 2.4.x (Java) 后在 Play Framework 中运行测试时出错

Posted

技术标签:

【中文标题】迁移到 2.4.x (Java) 后在 Play Framework 中运行测试时出错【英文标题】:Error running tests in Play Framework after migrating to 2.4.x (Java) 【发布时间】:2015-06-02 20:15:51 【问题描述】:

我刚刚从 2.3 迁移到 2.4。应用程序本身似乎正在运行,但没有任何测试将运行。它们都失败并出现以下错误:

[error] Test models.TestCountry.createTheater failed: com.google.inject.ProvisionException: Unable to provision, see the following errors:
[error] 
[error] 1) Error injecting constructor, java.lang.IllegalStateException: Got deeper than 5 levels while searching /home/jlei/workspace/ebor-play/target/web/classes/main/META-INF/resources/webjars
[error]   at controllers.WebJarAssets.<init>(WebJarAssets.scala:21)
[error]   at controllers.WebJarAssets.class(WebJarAssets.scala:21)
[error]   while locating controllers.WebJarAssets
[error]     for parameter 18 at router.Routes.<init>(Routes.scala:96)
[error]   while locating router.Routes
[error]   while locating play.api.test.FakeRouterProvider
[error]   while locating play.api.routing.Router
[error] 
[error] 1 error, took 2.828 sec
[error]     at com.google.inject.internal.InjectorImpl$2.get(InjectorImpl.java:1025)
[error]     at com.google.inject.internal.InjectorImpl.getInstance(InjectorImpl.java:1051)
[error]     at play.api.inject.guice.GuiceInjector.instanceOf(GuiceInjectorBuilder.scala:321)
[error]     at play.api.inject.guice.GuiceInjector.instanceOf(GuiceInjectorBuilder.scala:316)
[error]     at play.api.Application$class.routes(Application.scala:111)
[error]     at play.api.test.FakeApplication.routes(Fakes.scala:197)
[error]     at play.api.Play$.start(Play.scala:89)
[error]     at play.api.Play.start(Play.scala)
[error]     at play.test.Helpers.start(Helpers.java:450)
[error]     at play.test.WithApplication.startPlay(WithApplication.java:44)
[error]     ...
[error] Caused by: java.lang.IllegalStateException: Got deeper than 5 levels while searching /home/jlei/workspace/ebor-play/target/web/classes/main/META-INF/resources/webjars
[error]     at org.webjars.urlprotocols.FileUrlProtocolHandler.aggregateChildren(FileUrlProtocolHandler.java:43)
[error]     at org.webjars.urlprotocols.FileUrlProtocolHandler.aggregateChildren(FileUrlProtocolHandler.java:47)
[error]     at org.webjars.urlprotocols.FileUrlProtocolHandler.aggregateChildren(FileUrlProtocolHandler.java:47)
[error]     at org.webjars.urlprotocols.FileUrlProtocolHandler.aggregateChildren(FileUrlProtocolHandler.java:47)
[error]     at org.webjars.urlprotocols.FileUrlProtocolHandler.aggregateChildren(FileUrlProtocolHandler.java:47)
[error]     at org.webjars.urlprotocols.FileUrlProtocolHandler.aggregateChildren(FileUrlProtocolHandler.java:47)
[error]     at org.webjars.urlprotocols.FileUrlProtocolHandler.aggregateChildren(FileUrlProtocolHandler.java:47)
[error]     at org.webjars.urlprotocols.FileUrlProtocolHandler.listFiles(FileUrlProtocolHandler.java:36)
[error]     at org.webjars.urlprotocols.FileUrlProtocolHandler.getAssetPaths(FileUrlProtocolHandler.java:25)
[error]     at org.webjars.WebJarAssetLocator.getAssetPaths(WebJarAssetLocator.java:89)
[error]     at org.webjars.WebJarAssetLocator.getFullPathIndex(WebJarAssetLocator.java:119)
[error]     at controllers.WebJarAssets.<init>(WebJarAssets.scala:29)
[error]     at controllers.WebJarAssets$$FastClassByGuice$$db4380e1.newInstance(<generated>)
[error]     at com.google.inject.internal.cglib.reflect.$FastConstructor.newInstance(FastConstructor.java:40)
[error]     at com.google.inject.internal.DefaultConstructionProxyFactory$1.newInstance(DefaultConstructionProxyFactory.java:61)
[error]     at com.google.inject.internal.ConstructorInjector.provision(ConstructorInjector.java:105)
[error]     at com.google.inject.internal.ConstructorInjector.construct(ConstructorInjector.java:85)
[error]     at com.google.inject.internal.ConstructorBindingImpl$Factory.get(ConstructorBindingImpl.java:267)
[error]     at com.google.inject.internal.ProviderToInternalFactoryAdapter$1.call(ProviderToInternalFactoryAdapter.java:46)
[error]     at com.google.inject.internal.InjectorImpl.callInContext(InjectorImpl.java:1103)
[error]     at com.google.inject.internal.ProviderToInternalFactoryAdapter.get(ProviderToInternalFactoryAdapter.java:40)
[error]     at com.google.inject.internal.SingletonScope$1.get(SingletonScope.java:145)
[error]     at com.google.inject.internal.InternalFactoryToProviderAdapter.get(InternalFactoryToProviderAdapter.java:41)
[error]     at com.google.inject.internal.SingleParameterInjector.inject(SingleParameterInjector.java:38)
[error]     at com.google.inject.internal.SingleParameterInjector.getAll(SingleParameterInjector.java:62)
[error]     at com.google.inject.internal.ConstructorInjector.provision(ConstructorInjector.java:104)
[error]     at com.google.inject.internal.ConstructorInjector.construct(ConstructorInjector.java:85)
[error]     at com.google.inject.internal.ConstructorBindingImpl$Factory.get(ConstructorBindingImpl.java:267)
[error]     at com.google.inject.internal.InjectorImpl$2$1.call(InjectorImpl.java:1016)
[error]     at com.google.inject.internal.InjectorImpl.callInContext(InjectorImpl.java:1103)
[error]     at com.google.inject.internal.InjectorImpl$2.get(InjectorImpl.java:1012)
[error]     at com.google.inject.internal.InjectorImpl.getInstance(InjectorImpl.java:1051)
[error]     at play.api.inject.guice.GuiceInjector.instanceOf(GuiceInjectorBuilder.scala:321)
[error]     at play.api.inject.RoutesProvider$$anonfun$2.apply(BuiltinModule.scala:67)
[error]     at play.api.inject.RoutesProvider$$anonfun$2.apply(BuiltinModule.scala:67)
[error]     at scala.Option.fold(Option.scala:158)
[error]     at play.api.inject.RoutesProvider.get$lzycompute(BuiltinModule.scala:67)
[error]     at play.api.inject.RoutesProvider.get(BuiltinModule.scala:63)
[error]     at play.api.test.FakeRouterProvider.get$lzycompute(Fakes.scala:259)
[error]     at play.api.test.FakeRouterProvider.get(Fakes.scala:259)
[error]     at play.api.test.FakeRouterProvider.get(Fakes.scala:258)
[error]     at com.google.inject.internal.ProviderInternalFactory.provision(ProviderInternalFactory.java:81)
[error]     at com.google.inject.internal.BoundProviderFactory.provision(BoundProviderFactory.java:72)
[error]     at com.google.inject.internal.ProviderInternalFactory.circularGet(ProviderInternalFactory.java:61)
[error]     at com.google.inject.internal.BoundProviderFactory.get(BoundProviderFactory.java:62)
[error]     at com.google.inject.internal.InjectorImpl$2$1.call(InjectorImpl.java:1016)
[error]     at com.google.inject.internal.InjectorImpl.callInContext(InjectorImpl.java:1092)
[error]     at com.google.inject.internal.InjectorImpl$2.get(InjectorImpl.java:1012)
[error]     ... 44 more
[error] Failed: Total 1, Failed 1, Errors 0, Passed 0

我正在使用 InjectedRoutesGenerator 和 webjars-play 的 2.4.0-M3-1 版本。如果还有其他可能有帮助的细节,请告诉我!

有人知道会发生什么吗?

编辑:

挖出来:https://github.com/sbt/sbt-web/issues/104

所以似乎是一个已知问题。我想我会在此期间尝试找到一个创造性的解决方法......

【问题讨论】:

【参考方案1】:

失败的近因是:下有超过5级子目录:

/home/jlei/workspace/ebor-play/target/web/classes/main/META-INF/resources/webjars

See this source file for the source of the error.

【讨论】:

我确实有一些深度超过 5 层的 javascript 文件......我想我只是不明白为什么这是非法的事情?【参考方案2】:

这是 sbt-web 中的一个问题。他们提高了限制:https://github.com/sbt/sbt-web/issues/104

【讨论】:

【参考方案3】:

我通过模拟WebJarAssets 类在测试中解决了这个问题。扩展OneAppPerSuiteOneAppPerTest 的测试类中的基本虚假应用程序创建代码如下所示:

implicit override lazy val app: Application = new GuiceApplicationBuilder()
    .in(Environment(new File("."), this.getClass.getClassLoader, Mode.Test))
    .bindings(bind[WebJarAssets].toInstance(mock[WebJarAssets]))
    .build

在这里,我还混合了 org.scalatest.mock.MockitoSugar 特征,以便使用 mock 方法。 我不确定功能测试的情况是否需要完全构建的应用程序,其中WebJarAssets 可以使用。

【讨论】:

以上是关于迁移到 2.4.x (Java) 后在 Play Framework 中运行测试时出错的主要内容,如果未能解决你的问题,请参考以下文章

在 Play [2.4.x] 中是不是可以检测到 Twirl 模板的实际文件名?

Play 2.4.x - 资产复制

扩展 Play Framework 2.4.x 背后的方法

如何实现 flyway-play Java 迁移

通过路由为 IntelliJ 中导入的 Play 2.4.x 项目解析控制器

迁移到 Homestead 后在 PhpStorm 中为 Laravel 运行测试