unit-testing - 使用 Spock 和 Grails 在全局 stub 类中注入(inject) stub 协作者

标签 unit-testing grails dependency-injection spock stub

我正在使用 Grails 2.4.4 在 Spock 单元测试中渲染 GSP。 GSP 有许多自定义标记库,其中许多调用外部服务。问题是我无法将 stub 服务注入(inject)这些标记库,并且当我调用该服务时,它始终为空。这是我试图让最简单的案例工作的内容:

@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 上放置一个 setter/getter 并将其 stub ,但它也不起作用:

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

在标签库中:
BarService barService
BarService getBarService() { return barService }
//....
out << getBarService().something()

最后 ,唯一有效的(与 setter/getter )是这样的:
FooTagLib.metaClass.getBarService = { -> return Stub(BarService) }

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

我不确定如何将它的 stub 版本注入(inject) taglib。在我看来,其中至少一个应该有效,但显然我做错了什么。

最佳答案

这就是我为 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没有问题。如果您需要信息,请大声喊叫。

关于unit-testing - 使用 Spock 和 Grails 在全局 stub 类中注入(inject) stub 协作者,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27154673/

相关文章:

c# - 以编程方式更新容器内的配置

c# - 单元测试私有(private) Setter 问题(C#)

ios - Xcode在源代码中未显示OCMock验证错误

unit-testing - 如何避免 Go 中的重复测试?

grails - Gradle 搜索 zip 而不是 jar

java - Spring 2.5 托管 servlet : howto?

c# - 如何为未注册的服务注入(inject) null

unit-testing - Laravel:将测试组织到文件夹中并运行它们

grails - Spring Framework NoSuchMethodFound Tomcat错误

php - 如何从PHP调用Grails应用程序中定义的Web服务