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.


Related articles: