2013-03-06 86 views
7

目前升级的Grails 1.3.7应用2.1.0,并有一组过滤器,我想测试一下。看到grails documentation for testing filters表明现在支持过滤器的单元测试(推荐使用/在功能部分中提到,但没有找到示例),我试图将一些现有的过滤器集成测试转换为单元测试。的Grails 2.0的单元测试过滤器:服务注入和dependsOn

不过,我挣扎正确“嘲笑走”的过滤器这个过滤器dependsOn /起码正确地实现一些service S中的被注入过滤器进行模拟。

package com.example 

import ... // excluded for brevity 


class MyFilters { 

    GrailsApplication grailsApplication 
    SomeService someService 

    def dependsOn = [MyOtherFilters] 


    def filters = { 
     all(controller: 'controllerToExclude', invert: true) { 
      before = { 
       if (grailsApplication.config.someConfigProperty) { 
        def someProperty = request.getAttribute('MY_ATTRIBUTE') 

        if (someProperty = someService.someMethod()) { 
         redirect(url: someService.getNewUrl(session)) 
         return false 
        } 
       } 
       return true 
      } 
     } 
    } 
} 

而其他过滤器:

package com.example 

class MyOtherFilters { 

    SomeOtherService someOtherService 

    def filters = { 
     all(controller: '*', action: '*') { 
      before = { 
       def foo 

       if (params[MY_ATTRIBUTE]) { 
        foo = params[MY_ATTRIBUTE] 
        someOtherService.setMyAttribute(sitePreference, request) 
       } 

       if (!foo) { 
        foo = someOtherService.getMyAttribute(request) 
       } 

       if (foo) { 
        request.setAttribute('MY_ATTRIBUTE', foo) 
       }  

       return true 
      } 
     } 
    } 
} 

这两个过滤器我工作的一个非常骨架的简化版本(如果任何人的好奇,他们读移动VS桌面偏好,然后筛选基于该偏好)。

所以我写的测试看起来大致是这样的:

package com.example 

import grails.test.mixin.TestFor // ... etc more imports here 

@TestFor(SomeController) 
@Mock(MyFilters) // TODO what goes here??? 
class MyFiltersTests { 

    static final IPAD_USER_AGENT = 'Mozilla/5.0 (iPad; CPU OS 5_1 like Mac OS X; en-us) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9B176 Safari/7534.48.3' 
    static final NON_MOBILE_USER_AGENT = 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:7.0.1) Gecko/20100101 Firefox/7.0.12011-10-16 20:23:00' 


    void testFilterRedirects() { 
     grailsApplication.config.someConfigProperty = true 
     // actual filter logic acts on this user-agent through some service calls, would like to mock it out though  
     request.addHeader("user-agent", IPAD_USER_AGENT) 
     def result 

     withFilters(action: "index") { 
      result = controller.index() 
     } 

     //assertSomething on result perhaps 
     assertEquals "myExpectedRedirectUrl", response.redirectedUrl 
    } 
} 

因为这些代码代表,它甚至不执行MyFilters代码。我试着加入相关滤波器的嘲讽ALA:

@Mock([MyFilters, MyOtherFilters]) 

但后来我碰到与SomeOtherService方法被定义并不是问题,并没有找到一种方法来正确地嘲笑那些方法了(我该怎么办设置服务上的过滤器嘲笑?控制器或服务,您可以def myMock = mockFor(SomeOtherService),然后做controller.someOtherService = myMock.createMock()或类似的东西,但我不能找到一种方法来为与该withFilters块的文件是在暗示要使用过滤服务

理想情况下,我会嘲笑任何与someServiceMyOtherFilters有关的事情,只要写我的测试这个过滤器,但不知道什么是可能w /测试过滤器。

任何有识之士将不胜感激,非常感谢,如果你做了这一步!

回答

2

有同样的问题。有Grails中吉拉提出了一个错误http://jira.grails.org/browse/GRAILS-8976

我找到解决办法在http://delvingintodev.carrclan.us/2012/12/testing-grails-filters-that-use-services.html

你基本上有过滤器使用的服务如下

package xxx.me 

class MyFilters { 
    def filters = { 
     all(controller:'*', action:'*') { 
      before = { 
       applicationContext.getBean(MyService).doSomethingClever() 
      } 
     } 
    } 
} 

在这个“使用服务 测试Grails的过滤器”你将能够模拟它在单元测试的情况下

package xxx.me 

@TestMixin(GrailsUnitTestMixin) 
@Mock(MyFilters) 
class MyFiltersTests { 

    @Test 
    public void testFilter(){ 
     defineBeans { 
      myService(StubbedMyService) 
     } 
     SimpleController controller = mockController(SimpleController); 

     withFilters(controller:"simple" , action:"index"){ 
      controller.index()  
     } 
    } 
} 

class StubbedMyService extends MyService { 
    def doSomethingClever(){ 
    } 
} 
相关问题