如何在单元测试中绑定@Value注释的服务字段?

时间:2016-09-21 11:45:20

标签: grails spock

服务:

@GrailsCompileStatic
class MyService {
    final static String PLACEHOLDER = '<x>'

    @Value('${myService.url}')  // Suppose it http://example.com/doc-<x>.html 
    private String urlTemplate

    String getSomeUrl(String lang) {
        urlTemplate.replace(PLACEHOLDER, lang)
    }
}

单元测试:

@TestFor(MyService)
class MyServiceSpec extends Specification {

    @Unroll
    void "test get some url for #lang"() {
        when:
            def someUrl = service.getSomeUrl(lang) // NullPointerException, because urlTemplate is null
        then:
            someUrl.endsWith(lang + '.html')
        where:
            lang << ['es', 'en']
    }
}

因此,正如我上面提到的,urlTemplate为空(但.properties中存在配置值)。如何解决?

解决方案:

class MyServiceSpec extends IntegrationSpec {

    MyService myService

    @Unroll
    void "test get some url for #lang"() {
        when:
            def someUrl = myService.getSomeUrl(lang)
        then:
            someUrl.endsWith(lang + '.html')
        where:
            lang << ['es', 'en']
    }
}

2 个答案:

答案 0 :(得分:1)

单元测试用于测试隔离的代码单元。如果您正在测试依赖于配置值的行为,请将其注入单元测试以实现可重用的单元测试。

另一方面,如果您正在测试变量实际设置或变量设置为什么,则需要使用集成测试,因为您基本上是在测试与Grails配置机制的集成:{{3} }

作为第三种选择,您还可以使用功能测试来验证最终所有内容是否按预期运行:http://docs.grails.org/latest/guide/testing.html#integrationTesting

答案 1 :(得分:1)

  

如何在单元测试中绑定@Value带注释的服务字段?

一种方法......

@TestFor(MyService)
class MyServiceSpec extends Specification {

    @Unroll
    void "test get some url for #lang"() {
        when:
        service.urlTemplate = 'some value'
        def someUrl = service.getSomeUrl(lang)

        then:
        someUrl.endsWith(lang + '.html')

        where:
        lang << ['es', 'en']
    }
}