---
title: Spring Test Mode".
---
https://www.jianshu.com/p/e65226050463

# API單元測試-JUnt4
## 1.創建test
建立路徑 /src/test/java 以及 /src/test/resources,將撰寫的單元測試放在 /src/test/java,resources 下則放希望在測試環境下套用的資源檔
![Uploading file..._b3daxgn8w]()
### pom.xml中要添加依賴
```
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
```
---
### 1)在需要創建單元測試的controller上右鍵選——>go to——>test

### 2)選create New Test....

### 3)選擇需要單元測試的方法

### 4)創建完成

---
## 2.測試方法,如下
參考hungry
### MockMvc(模擬真實API)

### 1)登入測試
```typescript
import com.fasterxml.jackson.databind.ObjectMapper;
import com.tgfc.tw.MainApplication;
import org.hamcrest.Matchers;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.mock.web.MockHttpSession;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.WebApplicationContext;
import javax.servlet.http.Cookie;
import java.util.*;
@RunWith(SpringRunner.class)//RunWith就是一个運行器,定義測試程式要在Spring Boot的環境下運行
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = MainApplication.class)
//webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT啟動內置的容器,執行中會隨機生成一個port
@AutoConfigureMockMvc//代表測試時會在元件容器中建立MockMvc元件
public class UserControllerTest {
//資料格式轉換,轉成json字符串
private ObjectMapper objectMapper = new ObjectMapper();
@Autowired
private MockMvc mockMvc;//放登入後回傳的資料
MockHttpSession session;
//新增一個cookies陣列
Cookie[] cookies;
String xsrf;
@Autowired
WebApplicationContext webApplicationContext;
//執行任何方法前都會先執行init()
@Before
public void init() throws Exception {
//新增一個Map來放jasn格式的資料
Map<String, String> param = new HashMap<>();
param.put("account", "admin");
param.put("password", "123456");
//設呼叫路徑、HTTP METHOD(方法)、contentType(傳遞型態)、content(上傳資料)
MockHttpServletRequestBuilder requestBuilder =
MockMvcRequestBuilders.post("/api/login")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(param));
//執行 requestBuilder
MvcResult Resultu=mockMvc.perform(requestBuilder).andReturn();
//取cookies的值
cookies=Resultu.getResponse().getCookies();
//取session的值
session=(MockHttpSession)Resultu.getRequest().getSession();
//找出XSRF-TOKEN
for(Cookie cookie:cookies){
if(cookie.getName().equals("XSRF-TOKEN")){
xsrf= cookie.getValue();
}
}
}
```
### 2) 傳址方式傳遞引數
```typescript
//測試
@Test
//Rollback需要加上Transactional
@Transactional
//測完後還原
@Rollback
public void get() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.get("/api/user/get")
.session(session)
.param("id", "1")//傳值(Parameters),以傳址方式傳遞引數
.accept(MediaType.APPLICATION_JSON))//回傳格式
.andExpect(MockMvcResultMatchers.status().isOk())//驗證狀態是否200
.andDo(MockMvcResultHandlers.print());//印出
}
```
### 3) body傳值(Map接值)
```typescript
@Test
@Transactional
@Rollback
public void update() throws Exception {
Map<String, Object> param = new HashMap<>();
List<Integer> list=new ArrayList<>();
list.add(1);
param.put("id", 6);
param.put("name", "Amy2");
param.put("englishName", "Amy2");
param.put("floorId", 2);
param.put("permissions",list);
//呼叫路徑、HTTP METHOD(方法)、contentType(傳遞型態)、content(上傳資料)、
//設定cookie、設定header
mockMvc.perform(MockMvcRequestBuilders.put("/api/user/update")//新Post,刪Delete,修Put,查Get
.contentType(MediaType.APPLICATION_JSON_VALUE)//傳入json格式
.cookie(new Cookie("XSRF-TOKEN",xsrf))
.header("X-XSRF-TOKEN",xsrf)
.session(session)
.content(objectMapper.writeValueAsString(param))//json格式方法傳值
.accept(MediaType.APPLICATION_JSON))
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(MockMvcResultHandlers.print());
}
```
### 4) body傳值(JSONObject接值)
```typescript
@Test
@Transactional
@Rollback
public void update() throws Exception {
JSONObject request = new JSONObject();
request.put("id", 6);
request.put("name", "Amy2");
request.put("englishName", "Amy2");
request.put("floorId", 2);
request.put("permissions",list);
mockMvc.perform(MockMvcRequestBuilders.put("/api/user/update")
.contentType(MediaType.APPLICATION_JSON_VALUE)
.cookie(new Cookie("XSRF-TOKEN",xsrf))
.header("X-XSRF-TOKEN",xsrf)
.session(session)
.content(request.toString())
.accept(MediaType.APPLICATION_JSON))
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(MockMvcResultHandlers.print());
}
```
### 5) file傳值
```typescript
//file測試,無法使用@Rollback
@Test
public void uploadPhoto() throws Exception{
InputStream inputStream = new FileInputStream(new File("../hungry/src/test/resource/mc2.jpg"));
//File转MockMultipartFile
MockMultipartFile multipartFile = new MockMultipartFile("files", "1528095526.jpg", null, inputStream);
mockMvc.perform(MockMvcRequestBuilders
.multipart("/api/upload/photo")
.file(multipartFile)//file傳值
.contentType(MediaType.IMAGE_JPEG)//圖片格式上傳
.cookie(new Cookie("XSRF-TOKEN",xsrf))
.header("X-XSRF-TOKEN",xsrf)
.session(session)
.accept(MediaType.APPLICATION_JSON))
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(MockMvcResultHandlers.print());
}
@Test
public void getPhoto() throws Exception{
mockMvc.perform(MockMvcRequestBuilders.get("/api/images/{fileName}","1574668907557.jpg")
.contentType(MediaType.APPLICATION_FORM_URLENCODED)
.param("fileName", "1574668907557.jpg")
.cookie(new Cookie("XSRF-TOKEN",xsrf))
.header("X-XSRF-TOKEN",xsrf)
.session(session)
.accept(MediaType.APPLICATION_JSON))
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(MockMvcResultHandlers.print());
}
}
```
---
## 4.回傳資料
andDo(MockMvcResultHandlers.print())印出的測試資訊
```typescript
MockHttpServletRequest://Request的資料
HTTP Method = GET
Request URI = /api/orderHistory/getGroupByOrder
Parameters = {groupId=[339], storeId=[241], floorId=[1]}
Headers = [Content-Type:"application/json;charset=UTF-8", Accept:"application/json", X-XSRF-TOKEN:"cd71e913-dde7-440a-bb10-ca2b39bda4de", Cookie:"XSRF-TOKEN=cd71e913-dde7-440a-bb10-ca2b39bda4de"]
Body = null
Session Attrs = {SPRING_SECURITY_CONTEXT=org.springframework.security.core.context.SecurityContextImpl@fcf2e3eb: Authentication: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@fcf2e3eb: Principal: com.tgfc.tw.entity.model.response.user.UserResponse@497f8a4b; Credentials: [PROTECTED]; Authenticated: true; Details: null; Granted Authorities: ROLE_SUPER_MANAGER, ROLE_MANAGER}
Handler:
Type = com.tgfc.tw.controller.OrderHistoryController
Method = public java.util.List<com.tgfc.tw.entity.model.response.orderHistory.OrderHistoryCountOrderResponse> com.tgfc.tw.controller.OrderHistoryController.getGroupByOrder(int,int,java.lang.Integer)
MockHttpServletResponse://Response的回傳資料
Status = 200
Error message = null
Headers = [Set-Cookie:"XSRF-TOKEN=5c26d23d-51d0-4d40-991f-591ae4c86434; Path=/; HttpOnly", Content-Type:"application/json;charset=UTF-8", X-Content-Type-Options:"nosniff", X-XSS-Protection:"1; mode=block", Cache-Control:"no-cache, no-store, max-age=0, must-revalidate", Pragma:"no-cache", Expires:"0", X-Frame-Options:"SAMEORIGIN"]
Content type = application/json;charset=UTF-8
Body = [{"store":{"id":241,"storeName":"新增店家part2","storeTel":"04222655441","storeAddress":"","remark":"","tag":[],"pictures":[{"id":853,"storePictureUrl":"/api/images/1574651380569.jpg","storePicName":"1574651380569.jpg"}]},"countByOrder":[{"id":269,"name":"1便當","price":60,"count":2,"totalPrice":120,"content":[{"id":128,"name":"無","price":0,"count":2,"totalPrice":0,"orderPrice":0,"user":null}]}]}]
Forwarded URL = null
Redirected URL = null
Cookies = [[Cookie@5a5c041f name = 'XSRF-TOKEN', value = '5c26d23d-51d0-4d40-991f-591ae4c86434', comment = [null], domain = [null], maxAge = -1, path = '/', secure = false, version = 0, httpOnly = true]]
```
# H2資料庫
```xml=
//設定資料庫
spring.datasource.driver-class-name=org.h2.Driver
設定testdb資料庫
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.username=sa
spring.datasource.password=sa
```
## 創建資料表
1. 注意檔案有些語法和Mysql不同
2. exists:資料表不存在時創建
3. 注意名稱不可以改變

## 新增資料
1. 注意檔案檔案名稱不可以改變

# API單元測試-JUnt5
進用JUnt4
