当我启用启用国际化的Play Scala 2.6应用程序时,将呈现该页面,其中所有内容都从我的messages.en
文件中正确选取。
但是当我测试我的控制器时,其中一个测试在检查页面内容时失败了(contentAsString(result) must include ("Welcome to Play")
)。
测试失败,因为页面内容呈现为label.welcome_to_play
而不是Welcome to Play!
。仅当我从控制器的新实例渲染索引页时才会发生这种情况。当我通过从应用程序或路由器渲染页面进行测试时,相同的测试(contentAsString)正在传递。
你知道为什么会这样吗?
这是我的HomeController.scala
:
@Singleton
class HomeController @Inject()(cc: ControllerComponents)
extends AbstractController(cc) with I18nSupport {
def index() = Action { implicit request: Request[AnyContent] =>
Ok(views.html.index())
}
}
这是我的HomeControllerSpec.scala
测试:
class HomeControllerSpec extends PlaySpec
with GuiceOneAppPerTest
with Injecting
with Results {
"Calling HomeController.index" should {
"render the index page from a new instance of controller" in {
val controller = new HomeController(stubControllerComponents())
val result = controller.index().apply(FakeRequest(GET, "/"))
status(result) mustBe OK
contentType(result) mustBe Some("text/html")
// THIS IS WHERE THE TEST FAILS. Content appears as "label.welcome_to_play"
contentAsString(result) must include ("Welcome to Play")
}
"render the index page from the application" in {
val controller = inject[HomeController]
val home = controller.index().apply(FakeRequest(GET, "/"))
status(home) mustBe OK
contentType(home) mustBe Some("text/html")
// WHILE THIS IS PASSING
contentAsString(home) must include ("Welcome to Play")
}
"render the index page from the router" in {
val request = FakeRequest(GET, "/")
val home = route(app, request).get
status(home) mustBe OK
contentType(home) mustBe Some("text/html")
// AND THIS IS PASSING
contentAsString(home) must include ("Welcome to Play")
}
}
}
这是我的index.scala.html
观点:
@()(implicit messagesProvider: MessagesProvider)
@main(messagesProvider.messages("label.welcome_to_play")) {
<h1>@messagesProvider.messages("label.welcome_to_play")</h1>
}
这是我的messages.en
文件的样子:
label.welcome_to_play = Welcome to Play!
我的conf
文件中有以下配置:
play.i18n {
langs = [ "en" , "lv ]
}
我尝试将文件从messages.en
重命名为messages
,但没有帮助。
有谁知道测试失败的原因?为什么在从我的控制器的新实例渲染页面时没有使用消息文件?提前感谢您的帮助:)
答案 0 :(得分:0)
MessagesApi
由ControllerComponents
提供,其中包含邮件列表及其翻译。
当您使用stubControllerComponents
此will create MessagesApi
个对象并带有no messages的对象时。
如果您需要翻译的消息,则需要使用其他ControllerComponents
答案 1 :(得分:0)
我最终以testMessages
映射实例化DefaultMessagesApi,如下所示:
首先,我在testMessages
内创建了一个HomeControllerSpec
地图:
private val testMessages: Map[String, Map[String, String]] = Map(
"en" -> Map(
"label.welcome_to_play" -> "Welcome to Play!",
"label.hello_world" -> "Hello world"
)
)
此地图仅包含我要测试的标签的简短列表,而不是完整messages.en
文件的副本。
然后在失败的测试中,我通过覆盖HomeController
...
messagesApi
的新实例。
"render the index page from a new instance of controller" in {
val controller = new HomeController(stubControllerComponents()) {
override val messagesApi = new DefaultMessagesApi(testMessages)
}
val result: Future[Result] = controller.index().apply(FakeRequest(GET, "/"))
status(result) mustBe OK
contentType(result) mustBe Some("text/html")
contentAsString(result) must include ("Welcome to Play")
}
...测试通过了。
我承认这种方法会造成一些重复(messages.en
文件和规范内的消息标签),但是对于没有太多消息要测试的小型测试,我认为这是可以接受的解决方案。