Test

取得 profile 內的 server.port

當我們想要取得 yml 裡面設定的 port 時,會使用 @Value("${server.port}")

如果想要取得其他屬性,就修改大括號內的值,而在一般的屬性,都可以這樣直接取

但這裡面有一些隱藏的坑,像是取 port 的時候,會如下表

yml \ code

main

test

applicaition.yml

O

O

application-local.yml

O

X

這個表的意思是說,如果你直接把 server.port 寫在 application.yml 裡面,那很簡單,在 main 跟 test 裡面,都可以用上述方法直接取得。

但因為不同環境,會有相對應的配置文件,我們可以在 application.yml 只填寫

spring: 
  profiles: 
    active: local

而將 local 環境的配置,寫在 application-local.yml 這個配置文件裡

server: 
  port: 9999

這樣我們就可以根據不同的環境,在環境的 application.yml 去選擇對應的配置文件

但這樣當我們在測試程式裡,就沒辦法簡單的抓到 server.port 了

必須在我們的測試程式的類別上,加上這個註解

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)

參考資料:springboot test @value(“$ {server.port}”)(http://cn.voidcc.com/question/p-vkkqsybe-tz.html)

Conditional Test 根據註解的條件去決定是否執行測試

@EnabledOnOs 假如符合條件的作業系統,則執行這段測試

@Test
@EnabledOnOs({OS.WINDOWS, OS.MAC})
public void test(){
    //...
}

Super-powers are granted randomly so please submit an issue if you're not happy with yours.

Once you're strong enough, save the world:

// Ain't no code for that yet, sorry
echo 'You got to trust me on this, I saved the world'

MockMvc

參考資料:(https://medium.com/chikuwa-tech-study/spring-boot-%E7%AC%AC9%E8%AA%B2-%E4%BD%BF%E7%94%A8mockmvc%E8%87%AA%E5%8B%95%E5%8C%96%E6%B8%AC%E8%A9%A6-%E4%B8%80-3e3d031f8d68)

基本建置

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>

注意 此範例為 spring boot 2.1.2

@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class ProductTest {

    @Autowired
    private MockMvc mockMvc;

}

當spring boot 改為2.4.3時,要改為以下寫法

@RunWith(SpringRunner.class)
改為
@ExtendWith(SpringExtension.class)

參數設定

測試程式和原本業務邏輯的程式一樣,也有自己的設定檔。 因此請在src\test路徑下新增「resources」資料夾,建立「application.properties」檔案。 並添加測試程式使用的資料庫專屬位址。請不要與開發中程式使用相同的資料庫,避免互相影響。

範例

@Test
public void testCreateProduct() throws Exception {
    HttpHeaders httpHeaders = new HttpHeaders();
    httpHeaders.add("Content-Type", "application/json");

    JSONObject request = new JSONObject();
    request.put("name", "Harry Potter");
    request.put("price", 450);

    RequestBuilder requestBuilder =
            MockMvcRequestBuilders
                    .post("/products")
                    .headers(httpHeaders)
                    .content(request.toString());

    mockMvc.perform(requestBuilder)
            .andDo(print())
            .andExpect(status().isCreated())
            .andExpect(jsonPath("$.id").hasJsonPath())
            .andExpect(jsonPath("$.name").value(request.getString("name")))
            .andExpect(jsonPath("$.price").value(request.getInt("price")))
            .andExpect(header().exists("Location"))
            .andExpect(header().string("Content-Type", "application/json;charset=UTF-8"));
}

請求發出後,隨即透過「andExpect」方法進行回應資料的驗證。以下介紹在範例中使用到的驗證參數。

  1. 「status().isCreated()」:驗證HTTP狀態碼應為201。讀者可自行探索其他狀態,如「isOk」、「isNotFound」等。或透過「is」方法直接傳入狀態碼。

  2. 「jsonPath()」:指定JSON欄位。以「$」符號開始,使用「.」符號深入下一層的路徑。

  3. 「hasJsonPath()」:驗證某個JSON欄位存在。

  4. 「value()」:驗證某個JSON欄位值為何。

  5. 「header().exists()」:驗證回應標頭中的某欄位存在。

  6. 「header().string()」:驗證回應標頭中的某欄位值為何。

Response 亂碼

protected ResultActions getResponseEncoding(RequestBuilder builder) throws Exception {
        ResultActions resultActions = mockMvc.perform(builder);
        resultActions
                .andReturn()
                .getResponse()
                .setCharacterEncoding("UTF-8");
        return resultActions;
}

Last updated