Service:
@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)
    }
}
Unit test:
@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']
    }
}
So, as I mentioned above, urlTemplate is null (but config value exists in .properties). How to fix it?
Solution:
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']
    }
}
                Unit tests are used to test isolated units of code. If you are testing behavior that is dependent on the configuration value, inject it into the unit test to achieve reusable unit tests.
On the other hand, if you are testing that the variable is actually set or what the variable is set to, you need to use an integration test because you are basically testing your integration with Grails' configuration mechanism: http://docs.grails.org/latest/guide/testing.html#integrationTesting
As a third option, you could also use functional testing to verify that in the end everything appears to function as it is supposed to: http://docs.grails.org/latest/guide/testing.html#functionalTesting
How to bind @Value annotated fields of service in unit tests?
One way to do it...
@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']
    }
}
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With