2013-07-16 20 views
0

我有個域班組長的Grails 2的單元測試中產生,並且不按預期運行,併產生一個運行時間錯誤

class File { 
    String name 
    String path 

    static constraints = { 
     name nullable:false 
     path nullable:false 
    } 
} 

生成控制器

class FileController { 

static allowedMethods = [create: ['GET', 'POST'], edit: ['GET', 'POST'], delete: 'POST'] 

def index() { 
    redirect action: 'list', params: params 
} 

def list() { 
    params.max = Math.min(params.max ? params.int('max') : 10, 100) 
    [fileInstanceList: File.list(params), fileInstanceTotal: File.count()] 
} 

def create() { 
    switch (request.method) { 
    case 'GET': 
     [fileInstance: new File(params)] 
     break 
    case 'POST': 
     def fileInstance = new File(params) 
     if (!fileInstance.save(flush: true)) { 
      render view: 'create', model: [fileInstance: fileInstance] 
      return 
     } 

     flash.message = message(code: 'default.created.message', args: [message(code: 'file.label', default: 'File'), fileInstance.id]) 
     redirect action: 'show', id: fileInstance.id 
     break 
    } 
} 

def show() { 
    def fileInstance = File.get(params.id) 
    if (!fileInstance) { 
     flash.message = message(code: 'default.not.found.message', args: [message(code: 'file.label', default: 'File'), params.id]) 
     redirect action: 'list' 
     return 
    } 

    [fileInstance: fileInstance] 
} 

def edit() { 
    switch (request.method) { 
    case 'GET': 
     def fileInstance = File.get(params.id) 
     if (!fileInstance) { 
      flash.message = message(code: 'default.not.found.message', args: [message(code: 'file.label', default: 'File'), params.id]) 
      redirect action: 'list' 
      return 
     } 

     [fileInstance: fileInstance] 
     break 
    case 'POST': 
     def fileInstance = File.get(params.id) 
     if (!fileInstance) { 
      flash.message = message(code: 'default.not.found.message', args: [message(code: 'file.label', default: 'File'), params.id]) 
      redirect action: 'list' 
      return 
     } 

     if (params.version) { 
      def version = params.version.toLong() 
      if (fileInstance.version > version) { 
       fileInstance.errors.rejectValue('version', 'default.optimistic.locking.failure', 
          [message(code: 'file.label', default: 'File')] as Object[], 
          "Another user has updated this File while you were editing") 
       render view: 'edit', model: [fileInstance: fileInstance] 
       return 
      } 
     } 

     fileInstance.properties = params 

     if (!fileInstance.save(flush: true)) { 
      render view: 'edit', model: [fileInstance: fileInstance] 
      return 
     } 

     flash.message = message(code: 'default.updated.message', args: [message(code: 'file.label', default: 'File'), fileInstance.id]) 
     redirect action: 'show', id: fileInstance.id 
     break 
    } 
} 

def delete() { 
    def fileInstance = File.get(params.id) 
    if (!fileInstance) { 
     flash.message = message(code: 'default.not.found.message', args: [message(code: 'file.label', default: 'File'), params.id]) 
     redirect action: 'list' 
     return 
    } 

    try { 
     fileInstance.delete(flush: true) 
     flash.message = message(code: 'default.deleted.message', args: [message(code: 'file.label', default: 'File'), params.id]) 
     redirect action: 'list' 
    } 
    catch (DataIntegrityViolationException e) { 
     flash.message = message(code: 'default.not.deleted.message', args: [message(code: 'file.label', default: 'File'), params.id]) 
     redirect action: 'show', id: params.id 
    } 
} 

和測試用例

所生成的
@TestFor(FileController) 
@Mock(File) 
class FileControllerTests { 


def populateValidParams(params) { 
    assert params != null 
    params["name"] = 'someValidName' 
    params["path"] = 'someValidPath' 
} 

void testIndex() { 
    controller.index() 
    assert "/file/list" == response.redirectedUrl 
} 

void testList() { 

    def model = controller.list() 

    assert model.fileInstanceList.size() == 0 
    assert model.fileInstanceTotal == 0 
} 

void testCreate() { 
    def model = controller.create() 

    assert model.fileInstance != null 
} 

void testSave() { 
    controller.save() 

    assert model.fileInstance != null 
    assert view == '/file/create' 

    response.reset() 

    populateValidParams(params) 
    controller.save() 

    assert response.redirectedUrl == '/file/show/1' 
    assert controller.flash.message != null 
    assert File.count() == 1 
} 

void testShow() { 
    controller.show() 

    assert flash.message != null 
    assert response.redirectedUrl == '/file/list' 


    populateValidParams(params) 
    def file = new File(params) 

    assert file.save() != null 

    params.id = file.id 

    def model = controller.show() 

    assert model.fileInstance == file 
} 

void testEdit() { 
    controller.edit() 

    assert flash.message != null 
    assert response.redirectedUrl == '/file/list' 


    populateValidParams(params) 
    def file = new File(params) 

    assert file.save() != null 

    params.id = file.id 

    def model = controller.edit() 

    assert model.fileInstance == file 
} 

void testUpdate() { 
    controller.update() 

    assert flash.message != null 
    assert response.redirectedUrl == '/file/list' 

    response.reset() 


    populateValidParams(params) 
    def file = new File(params) 

    assert file.save() != null 

    // test invalid parameters in update 
    params.id = file.id 
    params["name"] = null 
    params["path"] = null 

    controller.update() 

    assert view == "/file/edit" 
    assert model.fileInstance != null 

    file.clearErrors() 

    populateValidParams(params) 
    controller.update() 

    assert response.redirectedUrl == "/file/show/$file.id" 
    assert flash.message != null 

    //test outdated version number 
    response.reset() 
    file.clearErrors() 

    populateValidParams(params) 
    params.id = file.id 
    params.version = -1 
    controller.update() 

    assert view == "/file/edit" 
    assert model.fileInstance != null 
    assert model.fileInstance.errors.getFieldError('version') 
    assert flash.message != null 
} 

void testDelete() { 
    controller.delete() 
    assert flash.message != null 
    assert response.redirectedUrl == '/file/list' 

    response.reset() 

    populateValidParams(params) 
    def file = new File(params) 

    assert file.save() != null 
    assert File.count() == 1 

    params.id = file.id 

    controller.delete() 

    assert File.count() == 0 
    assert File.get(file.id) == null 
    assert response.redirectedUrl == '/file/list' 
} 
} 

我已經爲傳遞和失敗的測試用例添加了正確的參數,但仍存在運行時錯誤並且在控制器中生成的代碼與測試用例中生成的代碼不匹配。測試用例調用控制器中不存在的方法。

這裏是錯誤碼/堆棧跟蹤

groovy.lang.MissingMethodException: No signature of method: FileController.update() is applicable for argument types:() values: [] 
Possible solutions: create(), putAt(java.lang.String, java.lang.Object), delete(), edit(), isCase(java.lang.Object), split(groovy.lang.Closure) 
    at FileControllerTests.testUpdate(FileControllerTests.groovy:98) 

所以有基本上由於控制器,用於編輯和高達日期沒有控制器的方法稱爲更新已被結合並使用將request.method =「POST」或'GET'休閒適當的行動。

所以基本上我的問題是如何獲得正確的單元測試用例來生成?還是我完全錯過了其他的東西?

我使用Grails 2.1.1

+0

您發佈的控制器代碼中沒有更新方法。這正是異常告訴你的。 – codelark

+0

是的,我看到了,但我想知道爲什麼控制器沒有生成正確的測試。 –

回答

0

因此,當我使用twitter引導腳手架文件更新模板文件時,就會出現這種差異。他們在腳手架中沒有更新的Test.groovy文件。

我不得不更新Test.groovy文件以對應於新的Controller.groovy文件。

1

你的代碼有看起來像鍋爐板腳手架模板,所以我假設你運行產生,對所有文件域類的一些點。這樣做可能會創建您的FileController和相應的FileControllerTest以及所有「crud」操作/測試。

只是走一個猜測在這裏,但在某些時候,你可能已經刪除了FileController你的更新動作,但留下的FileControllerTest到位,這給你留下

//in FileControllerTests 
void testUpdate() { 
    controller.update() 
    ... 
} 

只需更新測試類 - 刪除testUpdate或者如果您認爲以後需要它,請發表評論。

+0

是測試和控制器腳手架班不在水槽裏。我不確定他們是如何脫離接收器的,我無法找到與更新的控制器相匹配的測試代碼。我沒有在FileController中刪除我的更新。現在,該操作通過編輯來定義,並且在編輯中存在一個switch語句,該語句結合了較早的編輯/更新功能。我想也許我只需要鏈接到適當的Test.groovy模板代碼。但如果有人知道更多關於這個問題,請分享。 –