使用JSON RestfulController进行grails单元测试

时间:2014-09-30 18:15:50

标签: grails

我在为一个简单的控制器编写单元测试时遇到了问题,并且真正寻求帮助。

我的控制器:

package test.controller

import grails.converters.JSON
import grails.rest.RestfulController;
import grails.transaction.Transactional
import groovy.sql.GroovyRowResult
import groovy.sql.Sql
import javax.sql.DataSource

@Transactional(readOnly = true)
class ProjectController extends RestfulController {
    javax.sql.DataSource dataSource
    def projectService
    static responseFormats = ['json']

    def hello() {
        respond 'hello'
    }

    // project_vm is a db view and I coud not figure out mapping a domain for db view, so using sql
    def list(){
        Sql db = new Sql(dataSource)
        def result
        if (params.manager) {
            result = db.rows("SELECT * FROM project_vm where manager=:manager", [manager:params.manager])
        }else{
            result = db.rows("SELECT * FROM project_vm")
        }
        respond result
    }

从浏览器正常工作:

http://myhost/testproject/project/list
===>
[{"name":"prj1","manager":"testmanagerId1"}, {"name":"prj2","manager":"testmanagerId2"}]

但是单元测试失败并出现以下错误。我正在使用mysql。

package test.controller

import grails.test.mixin.TestMixin
import grails.test.mixin.support.GrailsUnitTestMixin
import spock.lang.Specification
import grails.test.mixin.TestFor
import test.domain.Project


@TestFor(ProjectController)
@Mock(Project)
class ProjectControllerSpec extends Specification {
    void "test something"() {
        given:
        new Project(name:"testproject", manager:"managerId").save(flush:true)

        when:
        request.method = 'GET'
        response.format = 'json'
        controller.list()

        then:
        response.status == 200
        (response.text).contains('testproject')
    }
}

我得到的错误是:

groovy.lang.GroovyRuntimeException: Ambiguous method overloading for method groovy.sql.Sql#<init>.
Cannot resolve which method to invoke for [null] due to overlapping prototypes between:
    [interface java.sql.Connection]
    [interface javax.sql.DataSource]
    at test.controller.ProjectController.$tt__list(ProjectController.groovy:37)
    at test.controller.ProjectControllerSpec.test something(ProjectControllerSpec.groovy:21)

1 个答案:

答案 0 :(得分:0)

我还建议切换到具有api抽象的Grails Api Toolkit。您的测试最终需要在架构中完成(即代理,消息队列等),而不仅仅是应用程序,并将所有内容绑定到控制器意味着测试已本地化。

Grails Api Toolkit允许在架构中共同关注; api的功能和数据被移动到通信层,可以在所有组件中共享,缓存和读取它们。

有关详细信息,请参阅此处的SpringOne幻灯片分享...

http://www.slideshare.net/bobdobbes/api-abstraction-api-chaining