網頁

2020/12/22

Maven Surefire Plugin run Spring Boot JUnit test pass environment variables

Maven Surefire Plugin執行Spring Boot的JUnit測試傳入環境變數的方法如下。

Maven Surefire Plugin執行測試的命令為mvn test,如果要帶入額外參數後面空一格加上-Dvar=value

例如輸入mvn test -Ddemo.var1=value1 -Ddemo.var2=value2則傳入兩變數demo.var1demo.var2demo.var1的值為value1demo.var2的值為value2

在Spring Boot中可透過@ValueEnvironment.getProperty(String key)取得傳入的變數值,因為傳入的參數會放入properties。參考「Spring Boot properties file value injection 屬性配置檔注入


範例環境:

  • Spring Boot 2.3.2.RELEASE
  • JUnit 5
  • Maven 3.6.3

下面DemoService bean中分別用@ValueEnvironment.getProperty()取得maven測試時命令行傳入的變數demo.var1demo.var2

DemoService

package com.abc.demo.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;

@Service
public class DemoService {

    @Value("${demo.var1}")
    private String var1;

    @Value("${demo.var2}")
    private String var2;

    @Autowired
    private Environment env;

    public String[] getVarsFromValueInject() {
        return new String[]{var1, var2};
    }

    public String[] getVarsFromEnvironment() {
        String var1 = env.getProperty("demo.var1");
        String var2 = env.getProperty("demo.var2");
        return new String[]{var1, var2};
    }

}

測試程式DemoServiceTests

DemoServiceTests

package com.abc.demo.service;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
public class DemoServiceTests {

    @Autowired
    private DemoService demoService;

    @Test
    public void getVarsFromValueInject() {
        String[] vars = demoService.getVarsFromValueInject();

        Assertions.assertEquals("hello", vars[0]);
        Assertions.assertEquals("world", vars[1]);
    }

    @Test
    public void getVarsFromEnvironment() {
        String[] vars = demoService.getVarsFromEnvironment();

        Assertions.assertEquals("hello", vars[0]);
        Assertions.assertEquals("world", vars[1]);
    }
    
}

在專案根目錄(pom.xml的目錄)開啟命令行用mvn test執行DemoServiceTests中的測試並帶入參數。
輸入mvn clean test -Dtest=DemoServiceTests -Ddemo.var1=hello -Ddemo.var2=world

..\spring-boot-demo>mvn clean test -Dtest=DemoServiceTests -Ddemo.var1=hello -Ddemo.var2=world
[INFO] Scanning for projects...
[INFO]
[INFO] ----------------------< com.abc:spring-boot-demo >----------------------
[INFO] Building spring-boot-demo 0.0.1-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-clean-plugin:3.1.0:clean (default-clean) @ spring-boot-demo ---
[INFO] Deleting ..\spring-boot-demo\target
[INFO]
[INFO] --- maven-resources-plugin:3.1.0:resources (default-resources) @ spring-boot-demo ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 1 resource
[INFO] Copying 1 resource
[INFO]
[INFO] --- maven-compiler-plugin:3.8.1:compile (default-compile) @ spring-boot-demo ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 2 source files to ..\spring-boot-demo\target\classes
[INFO]
[INFO] --- maven-resources-plugin:3.1.0:testResources (default-testResources) @ spring-boot-demo ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory ..\spring-boot-demo\src\test\resources
[INFO]
[INFO] --- maven-compiler-plugin:3.8.1:testCompile (default-testCompile) @ spring-boot-demo ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 2 source files to ..\spring-boot-demo\target\test-classes
[INFO]
[INFO] --- maven-surefire-plugin:2.22.2:test (default-test) @ spring-boot-demo ---
[INFO]
[INFO] -------------------------------------------------------
[INFO]  T E S T S
[INFO] -------------------------------------------------------
[INFO] Running com.abc.demo.service.DemoServiceTests

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.3.2.RELEASE)

2020-12-22 16:59:23.288  INFO 8636 --- [           main] c.a.d.s.DemoServiceTests                 : Starting DemoServiceTests on PC with PID 8636 (started ..\spring-boot-demo)
2020-12-22 16:59:23.296  INFO 8636 --- [           main] c.a.d.s.DemoServiceTests                 : No active profile set, falling back to default profiles: default
2020-12-22 16:59:24.169  INFO 8636 --- [           main] o.s.s.c.ThreadPoolTaskExecutor           : Initializing ExecutorService 'applicationTaskExecutor'
2020-12-22 16:59:24.407  INFO 8636 --- [           main] c.a.d.s.DemoServiceTests                 : Started DemoServiceTests in 1.402 seconds (JVM running for 2.44)
[INFO] Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 2.085 s - in com.abc.demo.service.DemoServiceTests
2020-12-22 16:59:24.599  INFO 8636 --- [extShutdownHook] o.s.s.c.ThreadPoolTaskExecutor           : Shutting down ExecutorService 'applicationTaskExecutor'
[INFO]
[INFO] Results:
[INFO]
[INFO] Tests run: 2, Failures: 0, Errors: 0, Skipped: 0
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  5.892 s
[INFO] Finished at: 2020-12-22T16:59:24+08:00
[INFO] ------------------------------------------------------------------------

若在其他配置(例如application.properties)有設定demo.var1demo.var2則其值會被命令列傳入的參數覆蓋。反之在其他配置檔沒設定demo.var1demo.var2且執行maven時也沒帶入參數的話啟動時會發生Failed to load ApplicationContext的錯誤,因為@Value無法解析發生java.lang.IllegalArgumentException: Could not resolve placeholder 'demo.var1' in value "${demo.var1}"


如果是以spring-boot-maven-plugin正常啟動Spring Boot並帶入參數,則輸入
mvn spring-boot:run -Dvar=value


沒有留言:

張貼留言