2014-09-30 77 views
0

我正在为一个简单的控制器编写单元测试的问题,并且真正在寻求帮助。用JSON实现grails单元测试RestfulController

我的控制器:从浏览器

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) 
+0

单元测试不完整配置Grails的环境中运行(即不依赖注入发生,所以你的'dataSource'引用为空)在你的情况下,我会建议使用集成测试而不是单元测试。 – 2014-09-30 20:40:47

回答

0

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

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

如需更多信息,请参阅本的SpringOne上SlideShare上...

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