2015-12-16 48 views
1

我有一個控制器,它在save方法中調用一個線程來檢索一些文件。線程已啓動()具有此LINE-Grails使用grails進行單元測試應用

RetrievalThread retrievalThread = grailsApplication.mainContext.getBean ('retrievalThread'). 

在我的單元測試我想這一個領域,它的工作(我會繼續省略了其他行有沒有影響現在)。如果沒有這一行,就會發生錯誤,說無法獲得null對象的mainContext,談論grailsApplication。 。

Def mainContext = Mock(ApplicationContext) 
MainContext.getBean(_) >>{ name -> 
return new MockRetrievalThread()} 

模擬線程不會執行任何操作。

這個測試運行良好,但是之後的任何測試都會失敗,出現空指針異常而沒有真正的信息。看起來像一堆背景grails的東西。有沒有辦法清理這個或使用比我使用的更好的東西?

+0

我遇到過這個問題,在使用常規測試時,grails \ grailsApplication沒有正確注入,通過集成測試運行整個應用程序解決了這個問題。你使用集成測試嗎? – shaydel

回答

1

我敢肯定有辦法在tearDown清理它,但我認爲這是一個更好的辦法。

1.)我會使用DI而不是通過grailsApplication.mainContext.getBean;你有這樣做的理由嗎?

class MyController { 
    def retrievalThread 

    getFiles() { 
     return [files: retrievalThread.getFiles(params.id)] 
    } 
} 

2.A.)使用DI,則可以只設置控制器retrievalThreadMockRetrievalThread一個新實例測試中。

void "test getFiles"() { 
    given: 
    controller.retrievalThread = new MockRetrievalThread() 

    when: 
    params.id = 1 
    def returnedFiles = controller.getFiles() 

    then: 
    // assertions 
} 

2.B.)或者完全跳過MockRetrievalThread並使用mockFor方法嘲笑retrievalThread豆,然後設置嘲笑版本注入的情況下在你的控制器。

void "test getFiles"() { 
    given: 
    def retrievalThreadMock = mockFor(RetrievalThread) 
    retrievalThreadMock.demand.getFiles { Integer input -> 
     return ['file1', 'file2', 'etc.'] 
    } 
    controller.retrievalThread = retrievalThreadMock.createMock() 

    when: 
    params.id = 1 
    def returnedFiles = controller.getFiles() 

    then: 
    // assertions 
} 
-1

您可以使用integration testing來運行整個應用程序,以避免任何bean未被注入。

grails create-integration-test org.bookstore.Book 
+0

,這並不是一個解決方案。單元測試有其自身的重要性,即一個單元單獨工作是否完美。集成測試是爲了確保這些單位在互相交談時運作良好,並且沒有溝通不暢。 –

+0

我已經回答了問題。「有沒有辦法清理這個問題或者使用比我使用的更好的方法?',不需要投票,因爲我的迴應提供了另一種成功運行測試的方法,在獲得grails bean時,集成在Tested對象和另一個grails services \ beans之間。 – shaydel