差異處

這裏顯示兩個版本的差異處。

連向這個比對檢視

下次修改
前次修改
java:spring:test:springinjunithellowworld [2019/01/30 22:54]
tony 建立
java:spring:test:springinjunithellowworld [2023/06/25 09:48] (目前版本)
行 1: 行 1:
 +{{tag>​java junit spring spring-test}}
 ====== Spring In JUnit HelloWorld! ====== ====== Spring In JUnit HelloWorld! ======
 ===== Introduction ===== ===== Introduction =====
 在寫這篇文章前,我只使用Spring Test去測試過我們的REST API。某一日,因為看到同事誤用的@ActiveProfile,讓我發現了其它不錯的Test Annotation。本篇文章分享給大家一些基本寫法。 在寫這篇文章前,我只使用Spring Test去測試過我們的REST API。某一日,因為看到同事誤用的@ActiveProfile,讓我發現了其它不錯的Test Annotation。本篇文章分享給大家一些基本寫法。
 +\\
 +\\
 +Note. 我使用的spring-test版本是4.3.6。
 ===== Load & Close Spring Context ===== ===== Load & Close Spring Context =====
 +下面這段是在修改之前的Load與Close Spring Context的程式碼,會註冊兩個Config,並將我們需要的物件綁定到此TestCase物件上:​ 
 +<code java> 
 +private AnnotationConfigApplicationContext springContext;​ 
 +@Before 
 +public void setup(){ 
 + springContext = new AnnotationConfigApplicationContext();​ 
 + springContext.setEnvironment(env);​ 
 + springContext.register( 
 + ModelConfig.class,​ 
 + MockConfig.class 
 + ); 
 +  
 + springContext.refresh();​ 
 +  
 + springContext.getAutowireCapableBeanFactory().autowireBean(this);​ 
 +
 +  
 +@After 
 +public void teardown(){ 
 + springContext.close();​ 
 +
 +</​code>​ 
 +上面冗長的程式碼,只要使用以下Annotation,就可以達到Load與Close:​ 
 +<code java> 
 +@RunWith(SpringRunner.class) 
 +@ContextConfiguration(classes={ModelConfig.class,​ MyTest.MockConfig.class}) 
 +public class RedfishSpringConfigTest { 
 + // skip 
 +
 +</​code>​ 
 +Runner要使用SpringRunner,而ContextConfiguration可以指定你要載入的Config class;假如你的config是xml形式,可以使用下面的寫法讓它去你的classpath找設定檔:​ 
 +<code java> 
 +@ContextConfiguration("​myconfig.xml"​) 
 +</​code>​ 
 +===== Get Bean ===== 
 +在執行測試過程中,一定會需要從Spring Context中取得你需要的Bean進行測試,以下是舊的寫法:​ 
 +<code java> 
 +AppController controller = springContext.getBean(AppController.class);​ 
 +</​code>​ 
 +在透過SpringRunner執行測試案例後,你可以直接在測試案例中綁定資源,以下是@Autowired寫法:​ 
 +<code java> 
 +@Autowired 
 +private AppController appController;​ 
 +</​code>​
 ===== Environment ===== ===== Environment =====
- +在你的Spring Config中,你可能會讀取properties並透過Environment去取得你要的參數;而測試中也免不了需要賦予這些參數來確認功能是否正常,以下是舊的寫法:​ 
 +<code java> 
 +MockEnvironment env = new MockEnvironment();​ 
 +env.setProperty("​interval",​ String.valueOf(expectedInterval));​ 
 +env.setProperty("​timeout",​ String.valueOf(expectedTimeout));​ 
 +  
 +springContext = new AnnotationConfigApplicationContext();​ 
 +springContext.setEnvironment(env);​ 
 +</​code>​ 
 +假如要將測試的MockEnvironment帶入Spring Context中,這時候就要依靠ApplicationContextInitializer:​ 
 +<code java> 
 +public static class EnvInitializer implements ApplicationContextInitializer<​ConfigurableApplicationContext>​ { 
 + @Override 
 + public void initialize(ConfigurableApplicationContext applicationContext) { 
 + MockEnvironment env = new MockEnvironment();​ 
 + env.setProperty("​interval",​ String.valueOf(expectedInterval));​ 
 + env.setProperty("​timeout",​ String.valueOf(expectedTimeout));​ 
 + applicationContext.setEnvironment(env);​ 
 +
 +
 +</​code>​ 
 +最後就是透過@ContextConfiguration載入這個EvnInitializer:​ 
 +<code java> 
 +@ContextConfiguration(classes={ModelConfig.class,​ MyTest.MockConfig.class},​initializers=MyTest.EvnInitializer.class) 
 +</​code>​ 
 +嗯..似乎要寫更多的code。其實還有另外一個方案,就是使用@TestPropertySource去指定參數:​ 
 +<​code>​ 
 +@TestPropertySource(properties={"​interval=123","​timeout=456"​}) 
 +</​code>​ 
 +但使用@TestPropertySource,如果要串變數上去,反而可讀性就不是這麼好了。
 ===== LifeCycle of the Spring Context ===== ===== LifeCycle of the Spring Context =====
 +在舊的寫法中,Spring Context的生命週期取決於我將Load與Close放在哪裡;而spring-text則是提供了@DirtiesContext讓你設定設定生命週期。用法如下,我指定在整個test suite執行後才清除context:​ 
 +<code java> 
 +@DirtiesContext(classMode=ClassMode.AFTER_CLASS) 
 +</​code>​ 
 +除了上面這個,常會使用的還有ClassMode.AFTER_EACH_TEST_METHOD。至於要用哪一種,可以好好思考,畢竟Spring的Load與Close是相當花時間的。
 ===== Reference ===== ===== Reference =====
   * [[https://​docs.spring.io/​spring/​docs/​current/​spring-framework-reference/​testing.html#​testing|Official Document]]   * [[https://​docs.spring.io/​spring/​docs/​current/​spring-framework-reference/​testing.html#​testing|Official Document]]
   * [[http://​blog.jamesdbloom.com/​UsingPropertySourceAndEnvironment.html|UsingPropertySourceAndEnvironment]]   * [[http://​blog.jamesdbloom.com/​UsingPropertySourceAndEnvironment.html|UsingPropertySourceAndEnvironment]]
   * [[https://​www.solidsyntax.be/​2013/​10/​22/​clean-the-spring-context-between-tests/​|Clean Spring Context]]   * [[https://​www.solidsyntax.be/​2013/​10/​22/​clean-the-spring-context-between-tests/​|Clean Spring Context]]
 +=====    ===== 
 +---- 
 +\\ 
 +~~DISQUS~~