2016-09-21 38 views
2

服務:如何在單元測試中綁定@Value帶註釋的服務字段?

@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'] 
    } 
} 

回答

1

單元測試用於測試的代碼分離單元。如果您正在測試依賴於配置值的行爲,請將其注入單元測試以實現可重用的單元測試。

在另一方面,如果你正在測試該變量實際上是設置或什麼變量被設置爲,你需要使用一個集成測試,因爲你基本上是用Grails的配置機制,測試您的集成:http://docs.grails.org/latest/guide/testing.html#integrationTesting

作爲第三種選擇,你也可以使用功能測試來驗證一切似乎功能到底,因爲它應該是:http://docs.grails.org/latest/guide/testing.html#functionalTesting

+0

「注射到單元測試,以實現可重複使用的單元測試」 - 我該怎麼辦呢?說實話,我在尋找這樣的東西:'@DearSpringInjectValuesPlease(from ='myconfig.properties')' – AndreyT

+0

注入值的最簡單方法是像傑夫斯科特布朗通過設置屬性來回答。但是,如果你堅持從你的屬性文件加載它,集成測試可能會更合適,否則你將不得不自己提出Grails的集成機制,冒着版本升級後代碼崩潰的風險。 –

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