使用MockMvc進(jìn)行controller層單元測(cè)試 事務(wù)自動(dòng)回滾的完整案例
看代碼吧~
package com.ieou.ms_backend.controller; import com.google.gson.Gson; import com.ieou.ms_backend.dto.account.CreateAccountReq; 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.MediaType; import org.springframework.test.annotation.Rollback; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MockMvcBuilder; import org.springframework.test.web.servlet.ResultActions; import org.springframework.test.web.servlet.ResultMatcher; import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import org.springframework.test.web.servlet.result.MockMvcResultHandlers; import org.springframework.test.web.servlet.result.MockMvcResultMatchers; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.context.WebApplicationContext; import static org.junit.Assert.*; /** * created by wyz on 2019/5/6 */ @SpringBootTest @RunWith(SpringJUnit4ClassRunner.class) public class AccountControllerTest { @Autowired private WebApplicationContext wac; private MockMvc mockMvc; private String url = "/ms_backend/account/"; @Before public void setUp() throws Exception{ //初始化MockMvc對(duì)象 mockMvc = MockMvcBuilders.webAppContextSetup(wac).build(); } //GET 請(qǐng)求 @Test public void accountList() throws Exception { MockHttpServletRequestBuilder mockHttpServletRequestBuilder = MockMvcRequestBuilders.get(url + "accountList") .param("companyName", "wang") .header("access_token", "accessToken"); mockHttpServletRequestBuilder.accept(MediaType.APPLICATION_JSON) .contentType(MediaType.APPLICATION_JSON_UTF8); ResultActions resultActions = mockMvc.perform(mockHttpServletRequestBuilder); resultActions.andReturn().getResponse().setCharacterEncoding("UTF-8"); resultActions.andExpect(MockMvcResultMatchers.status().isOk()); resultActions.andDo(MockMvcResultHandlers.print()); } @Test public void removeAccount() { } //post 請(qǐng)求 @RequestBody @Test @Transactional @Rollback() // 事務(wù)自動(dòng)回滾,默認(rèn)是true??梢圆粚? public void createAccount() throws Exception { CreateAccountReq req = new CreateAccountReq(); MockHttpServletRequestBuilder mockHttpServletRequestBuilder = MockMvcRequestBuilders.post(url + "createAccount") .header("access_token", "accessToken"); mockHttpServletRequestBuilder.accept(MediaType.APPLICATION_JSON) .contentType(MediaType.APPLICATION_JSON_UTF8) .content(new Gson().toJson(req)); // post請(qǐng)求 ResultActions resultActions = mockMvc.perform(mockHttpServletRequestBuilder); resultActions.andReturn().getResponse().setCharacterEncoding("UTF-8"); resultActions.andExpect(MockMvcResultMatchers.status().isOk()); resultActions.andDo(MockMvcResultHandlers.print()); } }
Spring-test 單元測(cè)試數(shù)據(jù)不自動(dòng)回滾的解決方案
在使用JUnit做單元測(cè)試時(shí),為了使測(cè)試數(shù)據(jù)不對(duì)數(shù)據(jù)庫(kù)造成污染,故選取了spring-test進(jìn)行單元測(cè)試,但在進(jìn)行dao層的測(cè)試時(shí),發(fā)現(xiàn)save方法無(wú)法進(jìn)行數(shù)據(jù)的自動(dòng)回滾。
逐一進(jìn)行檢查分析,事務(wù)也開(kāi)啟了,并使用注解方式標(biāo)記@RollBack(true),在控制臺(tái)中也打出了事務(wù)回滾的信息,但仍然不能自動(dòng)回滾。
后來(lái)感覺(jué)是數(shù)據(jù)庫(kù)的原因,我的數(shù)據(jù)庫(kù)使用的是MySql,這就存在數(shù)據(jù)表的類型是否支持事務(wù)情況。
逐查閱MySql相關(guān)文檔,發(fā)現(xiàn),InnoDB類型的表是支持事務(wù)的,而MyISAM是不支持事務(wù)的,立刻查看數(shù)據(jù)表類型,果然為MyISAM,改為InnoDB后,重新進(jìn)行測(cè)試,問(wèn)題得到解決。
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
詳解Java中finally和return的執(zhí)行順序
try-catch-finally是一種針對(duì)程序運(yùn)行時(shí)出錯(cuò)的響應(yīng)手段,對(duì)于一些可以預(yù)料到的出錯(cuò)類型,在發(fā)生時(shí)對(duì)其進(jìn)行報(bào)告和補(bǔ)救,這篇文章主要介紹了Java中finally和return的執(zhí)行順序,需要的朋友可以參考下2024-01-01SpringBoot中動(dòng)態(tài)數(shù)據(jù)源配置與使用詳解
在現(xiàn)代應(yīng)用中,處理多數(shù)據(jù)源是常見(jiàn)的需求,在 Spring Boot 中,這樣的需求可以通過(guò)動(dòng)態(tài)數(shù)據(jù)源來(lái)輕松實(shí)現(xiàn),本篇博客將詳細(xì)介紹如何在 Spring Boot 中配置和使用動(dòng)態(tài)數(shù)據(jù)源,并演示如何切換到指定的數(shù)據(jù)源,需要的朋友可以參考下2024-10-10Java基礎(chǔ)學(xué)習(xí)之反射機(jī)制原理詳解
反射是框架的靈魂,Java框架底層都是用反射機(jī)制+xml配置等來(lái)實(shí)現(xiàn)的,本文將通過(guò)示例詳細(xì)講解Java中的反射機(jī)制,感興趣的小伙伴可以跟隨小編學(xué)習(xí)一下2022-03-03一場(chǎng)由Java中Integer引發(fā)的踩坑實(shí)戰(zhàn)
Java中的數(shù)據(jù)類型分為基本數(shù)據(jù)類型和復(fù)雜數(shù)據(jù)類型int是前者而integer是后者(也就是一個(gè)類),下面這篇文章主要給大家介紹了關(guān)于由Java中Integer引發(fā)的踩坑實(shí)戰(zhàn),需要的朋友可以參考下2022-11-11防止SpringMVC攔截器攔截js等靜態(tài)資源文件的解決方法
本篇文章主要介紹了防止SpringMVC攔截器攔截js等靜態(tài)資源文件的解決方法,具有一定的參考價(jià)值,有興趣的同學(xué)可以了解一下2017-09-09