gpt4 book ai didi

unit-testing - 我如何在 play framework 2 scala 中对 Controller 进行单元测试

转载 作者:行者123 更新时间:2023-12-04 04:53:24 25 4
gpt4 key购买 nike

假设我有一个 Controller ,其 Action 接收两个参数。

它调用两个服务,一个带有每个参数,服务都返回字符串

每个字符串都作为参数传递给模板

结果传递给 Ok 并返回。

我想编写一个简单的单元测试来确保:
1 - 使用正确的参数调用正确的服务
2 - 服务的返回值传递给模板的正确属性

最好的方法是什么?

最佳答案

使用 Mockito 和 Specs2,我模拟服务来验证它们的方法调用。

我的 Controller 由 Spring 实例化。这让我可以将它视为 class而不是 object . => 这对于制作 controller 至关重要可测试。这里有一个例子:

@Controller
class MyController @Autowired()(val myServices: MyServices) extends Controller

要为 Controller 启用 Spring,您必须定义一个 Global对象,作为 Play !文档说明:
object Global extends GlobalSettings {

val context = new ClassPathXmlApplicationContext("application-context.xml")

override def getControllerInstance[A](controllerClass: Class[A]): A = {
context.getBean(controllerClass)
}
}

我的单元测试不需要 Spring;我只是将合作者(模拟)传递给构造函数。

但是,关于呈现的模板,我只测试结果类型(好的、BadRequest、重定向等...)。
事实上,我注意到让我的测试详细扫描整个渲染模板(发送给它的参数等)并不容易,只进行单元测试。

因此,为了断言使用正确的参数调用正确的模板,我相信我运行 Selenium 的验收测试,或者可能的功能测试,如果您愿意,可以扫描整个预期结果。

2 - The return values from the services are passed to the correct attributes of the template



检查它很容易..如何?通过信任编译器!更喜欢将一些自定义类型传递给您的模板,而不是简单的原语,例如: phone: String会变成: phone: Phone . (一个简单的值对象)。
因此,不必担心以非预期的顺序将属性传递给您的模板(在单元测试或实际生产代码中)。编译器确实会警告。

这是我使用 specs2 进行的单元测试(简化)之一的示例:
(您会注意到使用了包装器: WithFreshMocks )。
case class将允许在测试后刷新所有变量(在这种情况下为模拟)测试。
因此,这是重置模拟的好方法。
    class MyControllerSpec extends Specification with Mockito {

def is =
"listAllCars should retrieve all cars" ! WithFreshMocks().listAllCarsShouldRetrieveAllCars

case class WithFreshMocks() {

val myServicesMock = mock[MyServices]
val myController = new MyController(myServicesMock)

def listAllCarsShouldRetrieveAllCars = {
val FakeGetRequest = FakeRequest() //fakeRequest needed by controller
mockListAllCarsAsReturningSomeCars()
val result = myController.listAllCars(FakeGetRequest).asInstanceOf[PlainResult] //passing fakeRequest to simulate a true request
assertOkResult(result).
and(there was one(myServicesMock).listAllCars()) //verify that there is one and only one call of listAllCars. If listAllCars would take any parameters that you expected to be called, you could have precise them.
}

private def mockListAllCarsAsReturningSomeCars() {
myServicesMock.listAllCars() returns List[Cars](Car("ferrari"), Car("porsche"))
}

private def assertOkResult(result: PlainResult) = result.header.status must_== 200

}

关于unit-testing - 我如何在 play framework 2 scala 中对 Controller 进行单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17547466/

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