Play Framework with Internationalization测试失败

问题描述 投票:0回答:2

当我运行启用了国际化的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,但它没有帮助。

有谁知道测试失败的原因?为什么在从我的控制器的新实例渲染页面时没有使用消息文件?预先感谢您的帮助 :)

scala playframework internationalization playframework-2.6 twirl
2个回答
0
投票

MessagesApiControllerComponents提供,将包含消息列表及其翻译。

当你使用stubControllerComponents这个will create一个MessagesApi对象与no messages

如果您想要翻译的消息,则需要使用其他ControllerComponents


0
投票

我最终用DefaultMessagesApi地图实例化testMessages如下:

首先,我在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文件和Spec内部的消息标签)但是对于没有多少消息要测试的小测试,我认为这是一个可接受的解决方案。

© www.soinside.com 2019 - 2024. All rights reserved.