SpringBoot中MockMVC單元測(cè)試的實(shí)現(xiàn)
在編寫Springboot項(xiàng)目,如要對(duì)業(yè)務(wù)進(jìn)行測(cè)試時(shí),一般測(cè)試都是運(yùn)行項(xiàng)目,通過URL在postman或者chrome瀏覽器進(jìn)行測(cè)試,查看結(jié)果。
而當(dāng)項(xiàng)目十分大的時(shí)候,我們?cè)跍y(cè)試的時(shí)候,浪費(fèi)的時(shí)間較多,因此我們通過使用SpringBoot MVC來進(jìn)行單元測(cè)試。
可以實(shí)現(xiàn)對(duì)Http請(qǐng)求的模擬,能夠直接使用網(wǎng)絡(luò)的形式,轉(zhuǎn)換到Controller的調(diào)用,這樣可以使得測(cè)試速度快、不依賴網(wǎng)絡(luò)環(huán)境,而且提供了一套驗(yàn)證的工具,這樣可以使得請(qǐng)求的驗(yàn)證統(tǒng)一而且很方便。
如何使用MockMVC單元測(cè)試
Mock是一種用于模擬和替換類的對(duì)象的方法,以便在單元測(cè)試中獨(dú)立于外部資源進(jìn)行測(cè)試。使用Mock可以模擬各種對(duì)象,包括數(shù)據(jù)庫(kù)連接、網(wǎng)絡(luò)請(qǐng)求、外部服務(wù)調(diào)用等,以便在測(cè)試中檢查代碼的行為和輸出。
以下是如何使用Mock來編寫單元測(cè)試的步驟:
添加依賴
在項(xiàng)目的pom.xml文件中添加Mockito和JUnit的依賴。
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>3.12.4</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.8.1</version>
<scope>test</scope>
</dependency>
創(chuàng)建測(cè)試類
在測(cè)試目錄下創(chuàng)建一個(gè)新的測(cè)試類,例如MyServiceTest。
導(dǎo)入必要的類:在測(cè)試類中導(dǎo)入需要的類和注解。
import org.junit.jupiter.api.Test; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.MockitoAnnotations;
創(chuàng)建Mock對(duì)象
在測(cè)試類中使用@Mock注解創(chuàng)建需要Mock的對(duì)象。
@Mock private MyRepository myRepository;
初始化Mock對(duì)象
在測(cè)試類的@BeforeEach或@Before方法中初始化Mock對(duì)象。
@BeforeEach
void setUp() {
MockitoAnnotations.openMocks(this);
}
創(chuàng)建被測(cè)試的對(duì)象
在測(cè)試類中使用@InjectMocks注解創(chuàng)建被測(cè)試的對(duì)象,并將Mock對(duì)象注入到被測(cè)試對(duì)象中。
@InjectMocks private MyService myService;
編寫測(cè)試方法
在測(cè)試類中編寫測(cè)試方法,并使用Mock對(duì)象來模擬需要的行為。
@Test
void testSomeMethod() {
// 設(shè)置Mock對(duì)象的行為
when(myRepository.findById(1L)).thenReturn(Optional.of(new MyEntity()));
// 調(diào)用被測(cè)試的方法
MyEntity result = myService.findById(1L);
// 斷言結(jié)果
assertNotNull(result);
}
運(yùn)行測(cè)試
在測(cè)試類中右鍵點(diǎn)擊運(yùn)行測(cè)試方法,或者使用Maven命令運(yùn)行測(cè)試。
這樣就可以使用Mockito和JUnit來編寫單元測(cè)試了。Mockito提供了豐富的API來模擬對(duì)象的行為,使得單元測(cè)試更加簡(jiǎn)單和可控。
下面是某個(gè)模塊的增加和更新操作測(cè)試相關(guān)代碼如下(示例):
public class ClassificationControllerTest {
@InjectMocks
private ClassificationController classificationController;
private MockMvc mockMvc;
@Mock
private ClassificationService classificationService;
private ClassificationDto classificationDto;
private Gson gson = new Gson();
@Before
public void before(){
/*
首先,MockitoAnnotations.initMocks(this) 是一個(gè)靜態(tài)方法,用于初始化當(dāng)前類的所有帶有
@Mock 注解的 mock 對(duì)象。這個(gè)方法會(huì)自動(dòng)掃描當(dāng)前類中的所有字段,如果發(fā)現(xiàn)帶有 @Mock 注解的
字段,就會(huì)自動(dòng)初始化該字段對(duì)應(yīng)的 mock 對(duì)象
*/
MockitoAnnotations.initMocks(this);
/*
mockMvc = MockMvcBuilders.standaloneSetup(classificationController) 創(chuàng)建了一個(gè)
MockMvc 實(shí)例,用于模擬 Spring MVC 的請(qǐng)求和響應(yīng)。classificationController 是被測(cè)試的
控制器對(duì)象。
setControllerAdvice(new LocalExceptionAspect(), new GlobalExceptionHandler())
方法設(shè)置了兩個(gè) advices,用于處理控制器中拋出的異常。LocalExceptionAspect 是本地異常處理,
GlobalExceptionHandler 是全局異常處理。
*/
mockMvc = MockMvcBuilders.standaloneSetup(classificationController)
.setControllerAdvice(new LocalExceptionAspect(), new GlobalExceptionHandler())
.build();
classificationDto = new ClassificationDto();
classificationDto.setName("Test-Test");
classificationDto.setDescription("這是一個(gè)測(cè)試");
classificationDto.setColour("#ccc119");
}
@Test
public void add() throws Exception {
/*
MockMvc 是一個(gè)用于模擬 Spring MVC 請(qǐng)求和響應(yīng)的類。通過 mockMvc.perform() 方法,
可以創(chuàng)建一個(gè) MockMvc 請(qǐng)求對(duì)象,并指定請(qǐng)求的 URL、請(qǐng)求方法、請(qǐng)求頭、請(qǐng)求體等參數(shù)。
*/
MvcResult result= mockMvc.perform(MockMvcRequestBuilders.post("/classification/add") //請(qǐng)求方法為post ,請(qǐng)求的url
.accept(MediaType.APPLICATION_JSON) // 指定請(qǐng)求頭Accept 指定請(qǐng)求頭Content-Type
.contentType(MediaType.APPLICATION_JSON).content(gson.toJson(classificationDto))) //方法指定請(qǐng)求體位xxx對(duì)象的json字符串表示
.andReturn(); //返回一個(gè)MvcResult對(duì)象
int statusCode = result.getResponse().getStatus();
String content = result.getResponse().getContentAsString();
System.out.println("statusCode: "+statusCode);
System.out.println("返回結(jié)果 content: "+content);
Assert.assertEquals(200, statusCode); //驗(yàn)證響應(yīng)狀態(tài)碼是否為200,表示請(qǐng)求成功
/*
驗(yàn)證classificationService是否被調(diào)用了一次,并且傳入的參數(shù)類型是ClassificationDto類型。
這個(gè)方法用于確認(rèn)在測(cè)試用例執(zhí)行過程中,是否正確調(diào)用了相關(guān)的服務(wù)方法。
*/
verify(classificationService,times(1)).add(any(ClassificationDto.class));
}
@Test
public void update() throws Exception {
classificationDto.setId(119L);
MvcResult result= mockMvc.perform(MockMvcRequestBuilders.put("/classification/update")
.accept(MediaType.APPLICATION_JSON)
.contentType(MediaType.APPLICATION_JSON).content(gson.toJson(classificationDto)))
.andReturn();
int statusCode = result.getResponse().getStatus();
String content = result.getResponse().getContentAsString();
System.out.println("statusCode: "+statusCode);
System.out.println("返回結(jié)果 content: "+content);
Assert.assertEquals(200, statusCode);
verify(classificationService,times(1)).update(any(ClassificationDto.class));
}
}
總結(jié)
在上面的示例代碼中,我們首先使用了@Mock和@InjectMock注解來創(chuàng)建Mock對(duì)象并注入到測(cè)試類中。然后,我們可以定義了Mock對(duì)象的期望行為,當(dāng)被調(diào)用時(shí),返回一個(gè)包含測(cè)試數(shù)據(jù)的Optional對(duì)象。接下來,我們調(diào)用了被測(cè)試的方法,并獲取了返回值。最后,我們使用斷言語(yǔ)句來檢查方法的行為和輸出,包括驗(yàn)證被調(diào)用了一次,并驗(yàn)證返回值是否符合預(yù)期。
使用Mock可以有效地模擬外部依賴,使測(cè)試更加可控和可重復(fù)。這有助于提高測(cè)試的可靠性,并幫助開發(fā)人員更好地理解代碼的行為和輸出。
到此這篇關(guān)于SpringBoot中MockMVC單元測(cè)試的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)SpringBoot MockMVC單元測(cè)試內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot+MyBatis-Plus實(shí)現(xiàn)分頁(yè)功能
在SpringBoot項(xiàng)目中,結(jié)合MyBatis-Plus(簡(jiǎn)稱MP)可以非常方便地實(shí)現(xiàn)分頁(yè)功能,MP為開發(fā)者提供了分頁(yè)插件PaginationInterceptor,只需簡(jiǎn)單配置即可使用,本文給大家介紹了SpringBoot+MyBatis-Plus實(shí)現(xiàn)分頁(yè)功能,文中通過代碼示例給大家介紹的非常詳細(xì),需要的朋友可以參考下2024-01-01
Spring Boot 實(shí)現(xiàn)https ssl免密登錄(X.509 pki登錄)
這篇文章主要介紹了Spring Boot 實(shí)現(xiàn)https ssl免密登錄(X.509 pki登錄),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01
動(dòng)態(tài)代理模擬實(shí)現(xiàn)aop的示例
下面小編就為大家?guī)硪黄獎(jiǎng)討B(tài)代理模擬實(shí)現(xiàn)aop的示例。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧,希望對(duì)大家有所幫助2017-11-11

