2014-11-21 111 views
0

我正在使用Grails 2.3.8並嘗試爲使用服務的篩選器創建單元測試。使用模擬服務的單元測試篩選器

過濾器:

class LicenseFilters { 

    def licenseService 

    def filters = { 
     all(controller:'*', action:'*') { 
      before = { 
       if(!licenseService.checkLicense()){ 
        redirect(controller:"licenseExpired") 
        return false 
       } 
      } 
     } 
    } 
} 

該規範,第一次嘗試:

@TestFor(ExecutionTraceController) 
@Mock(LicenseFilters) 
class LicenseFiltersSpec extends Specification{ 
    void "Test filter redirects when license is wrong"() { 
     given:   
      LicenseFilters bean=applicationContext.getBean("com.nortia.sgmentia.license.LicenseFilters") 
      bean.licenseService=this.buildLicenseServiceStub(false)   
     when: 
      withFilters(action:"list") { 
       controller.list() 
      } 
     then: 
      response.redirectedUrl == '/licenseExpired' 
    } 

    private LicenseService buildLicenseServiceStub(boolean ok){ 
     LicenseService result=Stub(LicenseService) 
     result.checkLicense() >> ok 
     return result 
    } 
} 

但事實證明(由調試)說,我從上下文搶豆它是不一樣的因此我收到請求我仍然得到一個NPE

在第二次嘗試我嘗試使用defineBeans

void "Test filter redirects when license is wrong"() { 
    given:   
     defineBeans { 
      licenseService(MethodInvokingFactoryBean){ 
       targetObject = this 
       targetMethod= "buildLicenseServiceStub" 
       arguments=[false] 
      } 
     } 

    when: 
     withFilters(action:"list") { 
      controller.list() 
     } 
    then: 
     response.redirectedUrl == '/licenseExpired' 
} 

但嘲笑豆既不豆實例化,也不inyected。

我應該嘗試將服務手動輸入過濾器嗎? 發生了此問題https://jira.grails.org/browse/GRAILS-8976但它已關閉。

回答

0

我終於找到了一個解決方法,使它與第二種方法(使用defineBeans)一起工作。

服務沒有被自動裝配到過濾器所以最後手動與僞單做到了:

class LicenseFilters { 

    def licenseService 

    def filters = { 
     all(controller:'*', action:'*') { 
      before = { 
       if(!this.licenseService){ 
        this.licenseService=applicationContext.getBean("licenseService") 
       } 

       if(!this.licenseService.checkLicense()){ 
        redirect(controller:"licenseExpired") 
        return false 
       } 
      } 
     } 
    } 
} 

相當難看但溶液至少。 希望它可以幫助那裏的人。

0

我遇到過類似的情況,並且可以通過將服務添加到@Mock註釋中來修復它,即@Mock([LicenseFilters, LicenseService])

在你的情況下,規格看起來像以下:

@TestFor(ExecutionTraceController) 
@Mock([LicenseFilters, LicenseService]) 
class LicenseFiltersSpec extends Specification { 

    void "Test filter redirects when license is wrong"() { 
     given: 
     defineBeans { 
      licenseService(MethodInvokingFactoryBean) { 
       targetObject = this 
       targetMethod = "buildLicenseServiceStub" 
       arguments = [false] 
      } 
     } 

     when: 
     withFilters(action: "list") { 
      controller.list() 
     } 

     then: 
     response.redirectedUrl == '/licenseExpired' 
    } 

    private LicenseService buildLicenseServiceStub(boolean ok) { 
     LicenseService result = Stub(LicenseService) 
     result.checkLicense() >> ok 
     return result 
    } 
} 

注:以這種方式嘲諷服務將在默認情況下,注入實際LicenseService的實例到過濾器。所以,如果上面的defineBeans塊被移除,LicenseService.checkLicense()的實際實現將被調用。

相關問題