gpt4 book ai didi

scala - 如何对 Controller 传递给 Play Framework 中的 View 的参数执行测试

转载 作者:行者123 更新时间:2023-12-02 00:03:19 25 4
gpt4 key购买 nike

在我们的 play 应用程序中,每个 Controller 函数都从数据库(或其他方式)获取数据并将这些值传递给结果

def index = Action { implicit request =>
val newsItems: List[String] = fetchNewsFromDB()
Ok(views.html.home.index(newsItems))
}

def fetchNewsFromDB() = List("Headline1", "Headline2")

我正在使用规范编写测试(基于文档 http://www.playframework.com/documentation/2.2.x/ScalaTest)

根据 Controller 的文档如下。在下一个测试中,我想确保索引页包含标题。我通过检查是否存在类为“标题”的 div 来执行此操作

"Example Page#index" should {
"should contain a headline" in {
val controller = new TestController()
val result: Future[SimpleResult] = controller.index().apply(FakeRequest())
val bodyText: String = contentAsString(result)
bodyText.toLowerCase must contain("<div class=\"headline\"")
}
}

但是我宁愿检查 Controller 传递给 View 的列表 newsItems 是否是非空的。

最好的方法是什么?是否可以通过对 Controller 进行少量修改的通用方式实现这一点?

最佳答案

我也很沮丧,因为我无法在传递给模板的过程中拦截参数 - 事实上,如果您在您的页面中有很多“状态”(例如,提供用户对象、导航助手等的隐式)。

我最终做的是在我的 Controller 中添加一个额外的“接缝”以实现可测试性;在我的测试中,我扩展被测 Controller ,将 HTML 呈现函数替换为模拟函数,然后我可以使用它来验证参数。

这是一个基于您的“新闻”操作的简单示例;首先是 Controller ,它不再是一个对象,所以我们可以扩展它:

object Application extends ApplicationController

trait ApplicationController extends Controller {

def newsAction = Action {
Ok(renderNews("this is the news"))
}

def renderNews(s:List[String]):Html = html.sandbox(s)
}

renderNews 方法为我们提供了最重要的“测试接缝”。我认为它实际上也提高了 Controller 方法的可读性,这很好:-)

现在,单元测试:

class ApplicationSpec extends Specification with Mockito {

val mockedNewsRenderer = mock[List[String] => Html]

val controller = new ApplicationController {
override def renderNews(s:List[String]) = mockedNewsRenderer(s)
}

"Application News Controller" should {

"Pass a non-empty list of news items to the template" in {
val result = controller.newsAction(FakeRequest())

status(result) must beEqualTo(200)

val captor = ArgumentCaptor.forClass(classOf[List[String]])

there was one(mockedNewsRenderer).apply(captor.capture())
val theArgument = captor.getValue
theArgument.isEmpty must beFalse
}
}
}

我们创建一个模拟来代替 renderNews 函数,扩展 Controller 以便我们可以替换它(注意我们当然没有改变它的任何其他内容),并且然后正常调用操作。请注意,我们仍然得到一个标准的 Play Result,因此我们仍然可以检查状态代码等,但是我们可以使用 Mockito verify functionality that's built into Specs2 , 连同 Mockito's ArgumentCaptor facility断言我们的模板确实被调用了,并且它提供了一个非空的字符串列表。

这种方法对我来说效果很好 - 它可以通过快速运行且易于编写的单元测试获得非常好的 Controller 代码覆盖率。

关于scala - 如何对 Controller 传递给 Play Framework 中的 View 的参数执行测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20005032/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com