Complete case of controller layer unit test transaction automatic rollback using MockMvc
- 2021-09-12 01:23:22
- OfStack
Look at the code ~
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{
// Initialization MockMvc Object
mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();
}
//GET Request
@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 Request @RequestBody
@Test
@Transactional
@Rollback() // Transactions are automatically rolled back, and the default is true . You can not write
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 Request
ResultActions resultActions = mockMvc.perform(mockHttpServletRequestBuilder);
resultActions.andReturn().getResponse().setCharacterEncoding("UTF-8");
resultActions.andExpect(MockMvcResultMatchers.status().isOk());
resultActions.andDo(MockMvcResultHandlers.print());
}
}
Solution of Spring-test Unit Test Data Not Rollback Automatically
spring-test is selected for unit test in order to make the test data not pollute the database when JUnit is used for unit test, but when dao layer is tested, it is found that save method cannot automatically roll back the data.
After checking and analyzing one by one, the transaction is also opened, and @ RollBack (true) is marked with annotation. The transaction rollback information is also typed in the console, but it still cannot be rolled back automatically.
Later, I felt that it was the database. My database uses MySql, so there is a case whether the type of data table supports transactions.
Looking up the relevant documents of MySql one by one, it is found that the table of InnoDB type supports transactions, while the table of MyISAM does not support transactions. Immediately check the data table type, and it is MyISAM. After changing to InnoDB, it is tested again, and the problem is solved.