测试Controller
Maven依赖
xml
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
-
如果被测试的方法中使用了springSecurity框架,需要引入其依赖
xml<dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-test</artifactId> <scope>test</scope> </dependency>
测试类
-
找到需要测试的接口,快捷键【 ctrl+shift+t 】,创建测试类

-
创建测试类

-
此时便会在test下指定位置生成测试类,然后补全
javapackage com.ruoyi.project.ices.visualization.controller; import com.ruoyi.RuoYiApplication; import lombok.SneakyThrows; import lombok.extern.log4j.Log4j2; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MvcResult; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import org.springframework.test.web.servlet.result.MockMvcResultMatchers; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import org.springframework.web.context.WebApplicationContext; import java.nio.charset.StandardCharsets; import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; //这里是Springboot启动类 @SpringBootTest(classes = RuoYiApplication.class) @Log4j2 class DrivingControllerTest { @Autowired private WebApplicationContext wac; private MockMvc mockMvc; private HttpHeaders headers; private static final String baseUrl = "/hard/xxxxxx"; private static final String TOKEN = "Bearer eyJhbGciOiJxxxxxxxxxxxxx"; //下面全部方法测试执行前,都会先执行这里 @BeforeEach public void init(){ mockMvc = MockMvcBuilders .webAppContextSetup(wac) .apply(springSecurity()) // 关键:应用Spring Security配置 .alwaysDo(print()) // 打印请求响应信息,便于调试 .build(); MultiValueMap<String, String> headerMap = new LinkedMultiValueMap<>(); headerMap.add( "Authorization", TOKEN); headers = new HttpHeaders(); headers.addAll(headerMap); } @SneakyThrows @Test void siteLocationList() { MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders.post(baseUrl+ "/xxxxxxxx") .headers(headers) .contentType(MediaType.APPLICATION_JSON)) .andExpect(MockMvcResultMatchers.status().isOk()) .andReturn(); String contentAsString = mvcResult.getResponse().getContentAsString(StandardCharsets.UTF_8); log.info(contentAsString); } } -
执行覆盖率测试

-
此时控制台查看日志

-
右侧覆盖率测试

-
如果要测试其他类型的方法

-
如果要在请求体中传参数:
java@Autowired private ObjectMapper objectMapper; // JSON序列化 @SneakyThrows @Test void edit() { // 创建请求体(Map方式) Map<String, Object> requestBody = new HashMap<>(); requestBody.put("id", "xxxxxxxx-a500-4d7d-8c08-088339e6d2c5"); requestBody.put("remark", "测试修改内容"); // 转换为JSON字符串 String requestBodyJson = objectMapper.writeValueAsString(requestBody); MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders.put(baseUrl) .headers(headers) .contentType(MediaType.APPLICATION_JSON) .content(requestBodyJson)) //设置请求体 .andExpect(MockMvcResultMatchers.status().isOk()) .andReturn(); String contentAsString = mvcResult.getResponse().getContentAsString(StandardCharsets.UTF_8); log.info(contentAsString); }
白盒、单元测试service
Maven依赖
xml
<!-- JUnit 5 -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
<!-- Mockito -->
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>${mockito.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
测试类
- 和测试接口一样,创建测试类
java
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;
@Slf4j
@ExtendWith(
MockitoExtension.class) // JUnit 5 集成 Mockito
public class XXXXTest {
//被测试service
@InjectMocks
private TestServiceImpl testService;
//被Mock注解修饰的类,在测试方法中执行时,可以设置为代码桩
@Mock
private TestMapper testMapper;
//测试方法传入的参数
private TestVO query;
//桩方法返回的结果
private MockVO mockVO;
@BeforeEach
public void init(){
// 这里会在每个方法执行之前执行
//在这里初始化测试方法的参数
query = new TestVO();
//设置桩方法返回的结果
mockVO = new MockVO();
mockVO.setId(156l);
}
@Test
@DisplayName("测试xx功能 - 正常情况")
void test() {
//模拟mapper的行为,在下面testService测试方法执行时,testMapper.selectTetsVO(mockVO)无论如何,都会返回thenReturn中的mockVO。
when(testMapper.selectTetsVO(any(MockVO.class)))
.thenReturn(mockVO );
//执行测试方法
String result = testService.test方法(query)
log.info(result);
// 验证,可以验证很多,这里仅验证了非空
assertNotNull(result);
}
- Mock不是必须有的,关键看被测试的方法中是否用到了这个方法,而且这个方法的结果是否需要被忽略。
- 因为很多测试方法,只关心业务逻辑是否正常。
- 执行覆盖率测试,即可得到和接口测试一样的结果