2014-09-30 78 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