单元测试控制器方法?

Posted

技术标签:

【中文标题】单元测试控制器方法?【英文标题】:Unit testing a controller method? 【发布时间】:2010-05-17 01:05:21 【问题描述】:

我有一个这样的控制器方法:

def search = 
    def query = params.query

            ...

    render results as JSON

如何对此进行单元测试?具体来说,如何调用search设置params.query,如何测试render方法的结果?有没有办法模拟渲染方法?

【问题讨论】:

【参考方案1】:

子类grails.test.ControllerUnitTestCase 用于您的单元测试。 Grails 将自动实例化您的控制器并模拟渲染和重定向版本,以便您轻松测试结果。只需将测试输入分配给 controller.params 即可设置测试。

例子:

class SomethingController 
    def search = 
        def query = params.query
        ...stuff...
        render results as JSON
    

测试看起来像:

class SomethingControllerTests extends grails.test.ControllerUnitTestCase 
    void testSearch() 
        controller.params.query = "test query"
        controller.search()
        assertEquals "expected result", controller.response.contentAsString
    

注意:如果您需要完整的数据库集成环境,也可以使用 ControllerUnitTestCase 进行集成测试。

【讨论】:

【参考方案2】:

有两种方法可以对控制器进行单元测试,但需要您进行一些更改。

首先是对控制器本身进行单元测试,而不增加 http 解析的复杂性,因此您将编写单元测试并将 params.query 作为单元测试的一部分传递,因此,将您的搜索功能分成两个功能:

def search = 
  def query = params.query
  render realSearch(query) as JSON


def realSearch ...

所以,第一部分测试realSearch

然后第二部分是编写一个实际连接到您的 Web 应用程序的应用程序,并进行功能测试,这将测试您的整个应用程序,包括在第一部分中未测试的控制器部分。

【讨论】:

【参考方案3】:

TFM:Grails ref chapter 9

按照 testCreateWithJSON() 示例...只需将查询字符串填充到 params['query'] 中,设置 contentType,调用 search()。由于您明确调用渲染,最简单的事情是查看 response.contentAsString ...我可能只是对 contentAsString 进行模式匹配断言;您可以将其重新解析为 JSON,然后检查该对象树,但我怀疑这不会像简单的模式匹配断言那样清晰/快速。

【讨论】:

以上是关于单元测试控制器方法?的主要内容,如果未能解决你的问题,请参考以下文章

如何测试在视图控制器单元测试中设置私有变量的方法?

与单元测试控制器和服务方法的区别[重复]

单元测试控制器时无法模拟 Grails 服务方法 - MissingMethodException

笑话:在单元测试中禁用控制台的更好方法

如何将 @WebMvcTest 用于单元测试 POST 方法?

如何使用 Xcode 单元测试测试没有参数的 void 类方法