本文介紹一下SpringBoot中的測試方法
集成測試
@SpringBootTest
一個普通的web api
@RequestMapping
@RestController
public class HelloController {
@Autowired
RestTemplate restTemplate;
@GetMapping(value = "/api/hi")
public Map<String,Object> hello() {
String baiduRes = restTemplate.getForObject("https://www.baidu.com", String.class);
Map<String, Object> res = new HashMap<>();
res.put("status", "中");
res.put("msg", baiduRes);
return res;
}
}
測試類:
package xyz.bliu.sptest;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.web.client.RestTemplate;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@SpringBootTest
public class ControllerTest02 {
@Autowired
RestTemplate restTemplate;
@Autowired
MockMvc mockMvc;
@Test
public void restTemplateShouldNotNull() {
assertThat(restTemplate).isNotNull();
}
@Test
public void testGetRequest() throws Exception {
mockMvc.perform(get("/api/hi"))
.andExpect(status().isOk())
.andDo(print());
}
}
使用mockMvc好處是不會啟動真實的web服務(wù)
當(dāng)然你可以使用@SpingBootTest 并且注入一個RestTemplate來做真實的請求
假如希望僅僅測試controller層時, 可以使用另外一個注解
@WebMvcTest
他有一個參數(shù)可以指定測試的controller
package xyz.bliu.sptest;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.web.client.RestTemplate;
import xyz.bliu.sptest.controller.HelloController;
import static org.assertj.core.api.Assertions.*;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
@WebMvcTest(controllers = HelloController.class)
public class ControllerTest01 {
@Autowired
MockMvc mockMvc;
@MockBean
RestTemplate restTemplate;
@Test
public void helloShouldOK() throws Exception {
when(restTemplate.getForObject("https://www.baidu.com", String.class)).thenReturn("haha");
assertThat(mockMvc).isNotNull();
mockMvc.perform(get("/api/hi").header("kk", "v1")
.header("Content-Type", "application/json"))
.andDo(print())
.andExpect(content().contentType("application/json"))
.andExpect(content().json("{'status':'中', 'msg':'haha'}"));
}
@Test
public void restTemplateShouldBeNull() {
assertThat(restTemplate).isNull();
}
}
這樣僅會加載指定的controller和一些web層的東西不會加載其他Bean
假如這個controller中依賴其他的bean怎么辦呢?
答案是需要使用@MockBean去Mock依賴的行為
例如我這里的處理
@MockBean
RestTemplate restTemplate;
when(restTemplate.getForObject("https://www.baidu.com", String.class)).thenReturn("haha");
其實就是說當(dāng)調(diào)用restTemplate.getForObject(“https://www.baidu.com”, String.class)時,方法會返回“haha”
@WebMvcTest VS @SpringBootTest
顯然當(dāng)你只需要測試你的controller接收請求參數(shù)或者返回值時你可以使用@WebMvcTest, 因為它不需要加載整個application context, 因此會使你的test更快
然而當(dāng)需要集成測試時則需要@SpringBootTest
并且他們是不能同時使用的
-
另外你可能注意到了AssertJ 提供的 assertThat api非常好用,可以流式調(diào)用文章來源:http://www.zghlxwxcb.cn/news/detail-717477.html
-
另外本文測試環(huán)境為spring boot 3.x 和 Junit5
如果你使用是springboot 2.x 你可能還需要 @RunWith(SpringRuner.class) ( junit4)或者 @extendwith(springextension.class) (junit5)文章來源地址http://www.zghlxwxcb.cn/news/detail-717477.html
當(dāng)然你可以使用@SpingBootTest 并且注入一個RestTemplate來做真實的請求
package xyz.bliu.sptest;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.server.LocalServerPort;
import org.springframework.web.client.RestTemplate;
import java.util.Map;
import static org.assertj.core.api.Assertions.assertThat;
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class ControllerTest03 {
@Autowired
RestTemplate restTemplate;
@LocalServerPort
int port;
@Test
public void testGet() {
Map resp = restTemplate.getForObject("http://localhost:"+port+ "/api/hi", Map.class);
assertThat(resp.get("status").toString()).isEqualTo("中");
}
}
到了這里,關(guān)于【springboot單元測試,集成測試】的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!