2014-11-21 87 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()的实际实现将被调用。

相关问题