使用Spock和Grails在全球攻击类中注入Stub协作者

时间:2014-11-26 16:53:31

标签: unit-testing grails dependency-injection spock stub

我正在使用Grails 2.4.4在Spock单元测试中渲染GSP。 GSP有许多自定义标记库,其中许多都称为外部服务。问题是我无法在这些taglib中注入一个存根服务,当我调用该服务时,它总是为null。这就是我想要最简单的案例工作:

@TestMixin(GroovyPageUnitTestMixin)
@Mock(FooTagLib)
class MyGspSpec extends Specification {
    def setup() {
        def barStub = Stub(BarService)
        def tagLibStub = GroovyStub(FooTagLib, global:true) {

        }
        tagLibStub.barService = barStub
    }
    def 'test method'() {
        when: String result = render('myView', model:[:])
        then: assert result != null
    }
}

标签库:

class FooTagLib {
    static String namespace = "baz"
    BarService barService
    Closure<StreamCharBuffer> foo = { GroovyPageAttibutess attrs ->
        out << barService.something()
    }
}

_foo.gsp内容:

<baz:foo/>

我也试过这个:

FooTagLib.metaClass.barService = Stub(BarService) //also tried GroovyStub

我甚至尝试在taglib上放置一个getter并将其删除,但它也不起作用:

在设置中:

def barService = Stub(BarService)
GroovyStub(FooTagLib, global:true) {
    getBarService() >> barService
}

在taglib中:

BarService barService
BarService getBarService() { return barService }
//....
out << getBarService().something()

最后,唯一有效的(使用getter)就是:

FooTagLib.metaClass.getBarService = { -> return Stub(BarService) }

但这似乎是一个非常糟糕的黑客。

我不确定如何将它的存根版本注入taglib。在我看来,至少其中一个应该有用,但显然我做错了。

1 个答案:

答案 0 :(得分:0)

这就是我为tagLib传递单位规格的方法:

@TestFor(FooTagLib)
class FooTagLibSpec extends Specification {

    def setup() {
        // tagLib is available by default of above annotation is used
        tagLib.barService = Mock(BarService) {
            // Mock the service and stub the response
            1 * serviceMethod() >> { "Hello World Returns" }
        }
    }

    void "test something"() {
        expect: 'applying template would result in mocked response'
        applyTemplate('<baz:foo/>') == "Hello World Returns"
    }

    void "test taglib method call"() {
        expect:
        tagLib.foo() == "Hello World Returns"
    }
}

class FooTagLib {
    static defaultEncodeAs = [taglib:'html']
    static String namespace = "baz"    
    BarService barService

    Closure<StreamCharBuffer> foo = { attrs ->
        out << barService.serviceMethod()
    }
}

class BarService {
    def serviceMethod() { "Hello World" }
}

我希望我能够满足您在测试中寻找的检查点。您还可以看到规范可以毫无问题地模拟BarService。如果您需要信息,请大声喊叫。