我们正在将仅限Java的Play应用程序从Play 2.4迁移到Play 2.5。第一步:摆脱GlobalSettings
,仍然完全在2.4领域。我写了一些StartModule
,它将接管迁移指南和“互联网”描述的功能。我添加
play.modules.enabled += "de.[...].modules.StartModule"
到应用程序的.conf
文件。通过sbt run
或sbt start
执行此操作可按预期工作。但是,当我尝试使用sbt test
或sbt test-only
对这些内容进行单元测试时会出现大量问题。
我们有一个相当精细的单元测试设置,因为应用程序很复杂并且具有大量的遗留部件。最终,Play服务器的单元测试实例以
启动Helpers.start(testserver=Helpers.testServer(playhttpport,
app=new GuiceApplicationBuilder()
.configure(getConfiguration())
.build()));
只要上面的play.modules.enabled
行对单元测试代码不可见,此方法就可以正常工作。一旦启用它,我就会收到一些错误,比如
Test de.[...]Tests failed: com.google.inject.CreationException:
Unable to create injector, see the following errors:
1) No implementation for play.inject.ApplicationLifecycle was bound.
while locating play.inject.ApplicationLifecycle
或
2) Could not find a suitable constructor in play.api.Environment.
Classes must have either one (and only one) constructor annotated with @Inject
or a zero-argument constructor that is not private.
如果删除play.modules.enabled
行并将服务器启动更改为
Helpers.start(testserver=Helpers.testServer(playhttpport,
app=new GuiceApplicationBuilder()
.load(Guiceable.modules(new StartModule()))
.configure(getConfiguration())
.build()));
在我有限的理解中,如果给出了任何其他依赖关系定义,似乎GuiceApplicationBuilder
(或其他)“忘记”所有内置依赖项注入配置。不幸的是,我没有在这里或其他任何地方发现任何可以引导我找到解决方案的适用帖子。
问题:
任何见解和帮助都非常感谢! 亲切的问候, 德克
更新这是StartModule
:
public class StartModule extends AbstractModule {
@Override protected void configure() {
bind(InnerServerLauncher.class).asEagerSingleton();
}
}
这是InnerServerLauncher
:
@Singleton
public class InnerServerLauncher {
@Inject
public InnerServerLauncher(ApplicationLifecycle lifecycle,
Environment environment) {
System.err.println("*** Server launcher called ***");
}
}
我应该补充一点,如果我把一个完全不同的类放到play.modules.enabled
中,那么问题就出现了
play.modules.enabled += "play.filters.cors.CORSModule"
答案 0 :(得分:0)
好的,我终于明白了。问题是我在上面提到的GuiceBuilder.configure()
方法,但没有进一步详述。正如我所说,我们的系统中有很多遗产。因此,我们有一种机制,可以独立于Play的配置文件构建配置,以进行单元测试。 fakeApplication()
(以及基于play.modules.enabled
的方法)将其与Play内部配置合并,但仅限于最顶层。对于普通设置(字符串,数字等),这是正常的,但对于值列表,这意味着完整列表被覆盖并替换。
application.conf
来收集必须在依赖注入框架中注册的默认模块。文档非常清楚地表明您在play.modules.enabled
中的陈述只能向play.modules.enabled += "package.Module"
添加元素,即
play.modules.enabled
我们为单元测试构建配置环境的“特殊方式”,但是,只要设置了我们自己的配置中的任何值,覆盖播放自己的GuiceApplicationBuilder
。这破坏了Play的完整依赖注入方案,因为它自己的基类都不再可访问。无赖!
我通过实际使用“真实”配置文件解决了这个问题,该文件只是play.modules.enabled += ...
正常读取并且包含那些GuiceApplicationBuilder
行。由于此配置文件仍然是为单元测试场景人为地临时生成的,因此我通过System.setProperty
将其名称传递给System.setProperty("config.file",conffilename);
Helpers.start(testserver=Helpers.testServer(playhttpport,
app=new GuiceApplicationBuilder().build()));
:
play.modules.enabled
现在,正确创建配置并使用 GlobalSettings
的内部默认设置。现在,我终于可以开始实际将代码从{{1}}移动到注入且急切加载的模块中。这只是十个小时的狩猎......