我目前正在将我的应用从Play 2.4迁移到Play 2.5到目前为止,这是一个巨大的痛苦。
现在,我正试图让我的测试通过。
我有一个带有一些注入参数的控制器
class UserLogin @Inject() (
loginService: UserLoginService,
authConfig: AuthConfig,
oAuthConfig: OAuthConfig,
env: PureEnvironment,
//stringResources: StringResources,
messagesApi: MessagesApi
) extends BaseController(messagesApi: MessagesApi) {
//endpoints
}
从测试方面来看,我将它们定义为注入Guice
object IdentityManagerModuleMock extends AbstractModule with ScalaModule {
def configure: Unit = {
bind[PureEnvironment].toInstance(MockEnvironment)
val conf = Configuration.reference
val messagesApi = new DefaultMessagesApi(Environment.simple(), conf, new DefaultLangs(conf))
bind[MessagesApi].toInstance(messagesApi)
bind[AuthConfig].toInstance(
AuthConfig(
"https://localhost",
30,
3600,
86400,
Seq(InetAddress.getByName("127.0.0.1")),
Seq(InetAddress.getByName("127.0.0.1")),
"https://localhost/login"
)
)
bind[OAuthConfig].toInstance(oAuthConfigMock)
bind[UserLoginService].to[UserLoginServiceImpl]
}
val injector = Guice.createInjector(IdentityManagerModuleMock)
When I enable the routes in my routes file,
POST /login com.dummy.im.controllers.UserLogin.login
POST /reset com.dummy.im.controllers.UserLogin.reset
1) No implementation for com.dummy.im.components.UserLoginService was bound.
[info] while locating com.dummy.im.components.UserLoginService
[info] for parameter 0 at com.dummy.im.controllers.UserLogin.<init>(UserLogin.scala:24)
2) No implementation for com.dummy.platform.PureEnvironment was bound.
[info] while locating com.dummy.platform.PureEnvironment
[info] for parameter 3 at com.dummy.im.controllers.UserLogin.<init>(UserLogin.scala:24)
3) No implementation for scala.collection.Seq<java.net.InetAddress> was bound.
[info] while locating scala.collection.Seq<java.net.InetAddress>
[info] for parameter 4 at com.dummy.im.config.AuthConfig.<init>(AuthConfig.scala:13)
5) Could not find a suitable constructor in java.lang.Integer. Classes must have either one
(and only one) constructor annotated with @Inject or a zero-argument constructor that is not private.
[info] at java.lang.Integer.class(Integer.java:52)
[info] while locating java.lang.Integer
[info] for parameter 1 at com.dummy.im.config.AuthConfig.<init>(AuthConfig.scala:13)
奇怪的是,我有一个非常类似于实际运行应用程序的配置,没有MessagesAPI(据我所知,由Play注入)和那些从.conf文件中读取的配置对象。
object IdentityManagerModule extends AbstractModule with ScalaModule {
def configure: Unit = {
bind[PureEnvironment].to[PlayProductionEnvironmentImpl]
bind[OauthRepository].to[OauthRepositoryImpl]
bind[UserLoginService].to[UserLoginServiceImpl]
}
}
它运行得很好。
我改变的主要是将依赖项添加到控制器中的MessagesAPI。
我不明白为什么Guice无法看到IdentityManagerModuleMock中绑定的内容。
任何想法都受到欢迎。在过去的几天里,我已经阅读并尝试了所有我想到的。
编辑: 我们有一个自定义应用程序加载器
class CustomApplicationLoader extends GuiceApplicationLoader() {
//config validation
override def builder(context: ApplicationLoader.Context): GuiceApplicationBuilder = {
val conf = context.initialConfiguration
initialBuilder
.in(context.environment)
.loadConfig(conf)
.overrides(overrides(context): _*)
.bindings(
MiscModule,
CommonConfigurationModule,
IdentityManagerConfigModule,
IdentityManagerModule,
ApplicationLifecycleModule
)
}
}
在.conf文件中,它用作
play.application.loader = "com.dummy.guice.CustomApplicationLoader"
答案 0 :(得分:1)
看起来您不需要为自己所做的事情定制应用程序加载器。如果您禁用开箱即用的MessagesApi,然后通过application.conf
添加自己的模块,这意味着您不必覆盖MessagesApi。
https://www.playframework.com/documentation/2.5.x/ScalaPlayModules#Registration-Overrides
如果您正在运行涉及Guice的测试,则可以使用WithApplication
。
https://www.playframework.com/documentation/2.5.x/ScalaFunctionalTestingWithSpecs2#WithApplication
您不应该直接调用Guice.createInjector
,因为WithApplication会调用GuiceApplicationBuilder:
https://www.playframework.com/documentation/2.5.x/ScalaTestingWithGuice#GuiceApplicationBuilder
查看示例项目:它们都有“2.5.x”分支,大多数都集成了测试,并将它们作为指南:
https://github.com/playframework?utf8=%E2%9C%93&q=examples&type=&language=