加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

单元测试 – 如何在play framework 2 scala中对控制器进行单元测

发布时间:2020-12-16 19:15:56 所属栏目:安全 来源:网络整理
导读:假设我有一个控制器,其动作可以接收两个参数. 它调用两个服务,每个参数一个,服务都返回字符串 每个字符串都作为参数传递给模板 结果传递给Ok并返回. 我想写一个简单的单元测试来确保: 1 – 使用正确的参数调用正确的服务 2 – 服务的返回值将传递给模板的正
假设我有一个控制器,其动作可以接收两个参数.

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

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

结果传递给Ok并返回.

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

最好的方法是什么?

解决方法

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

我的控制器由Spring实例化.这允许我将它视为一个类而不是对象. =>这对于使控制器可测试至关重要.这是一个例子:

@Controller
class MyController @Autowired()(val myServices: MyServices) extends 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;我只是将协作者(模拟)传递给构造函数.

但是,关于渲染模板,我只测试结果类型(Ok,BadRequest,Redirection等…).
实际上,我注意到让我的测试扫描整个渲染模板的详细信息(发送给它的参数等等)并不容易,只进行单元测试.

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

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

这很容易检查……怎么样?通过信任编译器!更喜欢将一些自定义类型传递给模板而不是简单的基元,例如:
电话:字符串将成为:电话:电话. (一个简单的价值对象).
因此,不必担心以非预期的顺序将属性传递给模板(在单元测试或实际生产代码中).编译器确实会警告.

以下是使用specs2进行单元测试(简化)的示例:
(您将注意到使用包装器:WithFreshMocks).
此案例类允许在测试后刷新所有变量(在这种情况下为模拟)测试.
这是重置模拟的好方法.

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

       }

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读