【问题标题】:Grails 2.0 Unit-Testing Filters: service injection and dependsOnGrails 2.0 单元测试过滤器:服务注入和依赖
【发布时间】:2013-03-06 01:05:38
【问题描述】:

目前正在将一个 grails 1.3.7 应用程序升级到 2.1.0,并且有一组我想测试的过滤器。看到 grails documentation for testing filters 表明现在支持过滤器的单元测试(/推荐?它在功能部分中提到但没有找到示例),我正在尝试将过滤器的一些现有集成测试转换为单元测试。

但是,我正在努力正确地“模拟”一个过滤器这个过滤器dependsOn/至少正确地为一些注入过滤器的services 实现一个模拟。

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
            }
        }
    }
}

这是我正在使用的两个过滤器的真正骨架简化版本(如果有人好奇,他们会阅读移动设备与桌面设备的偏好,然后根据该偏好进行过滤)。

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

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 方法未定义的问题,并且没有找到正确模拟这些方法的方法(如何在过滤器上设置服务模拟?在控制器或服务上你可以@ 987654330@ 然后执行controller.someOtherService = myMock.createMock() 或类似的操作,但我找不到使用文档建议使用的withFilters 块为过滤器设置服务的方法。

理想情况下,我会嘲笑与 someService 和 MyOtherFilters 相关的任何事情,只是在此过滤器上编写我的测试,但不确定测试过滤器有什么可能。

任何见解都将不胜感激,如果您能做到这一点,非常感谢!

【问题讨论】:

    标签: unit-testing grails filter


    【解决方案1】:

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

    我在http://delvingintodev.carrclan.us/2012/12/testing-grails-filters-that-use-services.html“测试使用服务的 Grails 过滤器”中找到了解决方法 '

    您基本上必须在过滤器中使用服务,如下所示

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

    在这种情况下,您将能够在单元测试中模拟它

    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(){
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2012-12-23
      • 2015-06-24
      • 2018-03-03
      • 1970-01-01
      • 2021-06-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多