在Spring Boot应用程序中,使用MockMvc进行单元测试是一种有效的方式,可以验证控制器的行为和API的正确性。在这篇博客中,我们将介绍如何使用MockMvc对用户控制器(UserController)进行测试,该控制器涉及用户信息的增删改查操作。
package com.lfsun.mockmvc;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.lfsun.mockmvc.entity.User;
import com.lfsun.mockmvc.service.UserService;
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.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import java.util.Arrays;
import java.util.List;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class UserControllerTest {
@Autowired
private MockMvc mockMvc;
@Autowired
private UserService userService;
@Autowired
private ObjectMapper objectMapper;
@Before
public void setUp() {
// 在测试前初始化一些数据,或者使用Mockito进行一些mock设置
}
@Test
public void getAllUsersTest() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.get("/user/getAllUsers"))
.andExpect(status().isOk())
.andExpect(jsonPath("$").isArray())
.andExpect(jsonPath("$.length()").value(userService.getAllUsers().size()))
.andDo(print());
}
@Test
public void getUserByIdTest() throws Exception {
Long userId = 1L;
mockMvc.perform(MockMvcRequestBuilders.get("/user/getUserById/{userId}", userId))
.andExpect(status().isOk())
.andExpect(jsonPath("$.userId").value(userId))
.andDo(print());
}
@Test
public void addUserTest() throws Exception {
User user = new User();
user.setUsername("testUser");
user.setEmail("[email protected]");
mockMvc.perform(MockMvcRequestBuilders.post("/user/addUser")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(user)))
.andExpect(status().isOk())
.andExpect(jsonPath("$.username").value("testUser"))
.andExpect(jsonPath("$.email").value("[email protected]"))
.andDo(print());
}
@Test
public void updateUserTest() throws Exception {
Long userId = 1L;
User updatedUser = new User();
updatedUser.setUserId(userId);
updatedUser.setUsername("updatedUser");
updatedUser.setEmail("[email protected]");
mockMvc.perform(MockMvcRequestBuilders.put("/user/updateUser")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(updatedUser)))
.andExpect(status().isOk())
.andExpect(jsonPath("$.userId").value(userId))
.andExpect(jsonPath("$.username").value("updatedUser"))
.andExpect(jsonPath("$.email").value("[email protected]"))
.andDo(print());
}
@Test
public void deleteUserTest() throws Exception {
Long userId = 1L;
mockMvc.perform(MockMvcRequestBuilders.delete("/user/deleteUser/{userId}", userId))
.andExpect(status().isOk())
.andDo(print());
}
}
@Autowired
注解用于将MockMvc实例注入测试类中。@Before
注解的 setUp
方法,可以在测试前进行一些数据初始化或使用Mockito进行一些mock设置。ObjectMapper
负责将对象序列化为JSON,以便在POST和PUT请求中传递。controller:
package com.lfsun.mockmvc.controller;
import com.lfsun.mockmvc.entity.User;
import com.lfsun.mockmvc.service.UserService;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 用户 Controller
*
* @author CL
*/
@RestController
@RequestMapping(value = "/user")
@RequiredArgsConstructor
public class UserController {
private final UserService userService;
// 查询所有用户
@GetMapping("/getAllUsers")
public List getAllUsers() {
return userService.getAllUsers();
}
// 根据用户ID查询用户
@GetMapping("/getUserById/{userId}")
public User getUserById(@PathVariable Long userId) {
return userService.getUserById(userId);
}
// 添加用户
@PostMapping("/addUser")
public User addUser(@RequestBody User user) {
return userService.addUser(user);
}
// 更新用户信息
@PutMapping("/updateUser")
public User updateUser(@RequestBody User user) {
return userService.updateUser(user);
}
// 根据用户ID删除用户
@DeleteMapping("/deleteUser/{userId}")
public void deleteUser(@PathVariable Long userId) {
userService.deleteUser(userId);
}
}
service、serviceimpl
package com.lfsun.mockmvc.service;
import com.lfsun.mockmvc.entity.User;
import java.util.List;
/**
* 用户 Service 接口
*/
public interface UserService {
// 查询所有用户
List getAllUsers();
// 根据用户ID查询用户
User getUserById(Long userId);
// 添加用户
User addUser(User user);
// 更新用户信息
User updateUser(User user);
// 根据用户ID删除用户
void deleteUser(Long userId);
}
package com.lfsun.mockmvc.service.impl;
import com.lfsun.mockmvc.entity.User;
import com.lfsun.mockmvc.mapper.UserMapper;
import com.lfsun.mockmvc.service.UserService;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* 用户 Service 实现类
*/
@Service
@AllArgsConstructor // Lombok 自动生成构造函数
public class UserServiceImpl implements UserService {
private final UserMapper userMapper;
@Override
public List getAllUsers() {
return userMapper.getAllUsers();
}
@Override
public User getUserById(Long userId) {
return userMapper.getUserById(userId);
}
@Override
public User addUser(User user) {
userMapper.addUser(user);
return user;
}
@Override
public User updateUser(User user) {
userMapper.updateUser(user);
return user;
}
@Override
public void deleteUser(Long userId) {
userMapper.deleteUser(userId);
}
}
mapper
package com.lfsun.mockmvc.mapper;
import com.lfsun.mockmvc.entity.User;
import org.apache.ibatis.annotations.*;
import java.util.List;
/**
* 用户 Mapper 接口
*/
@Mapper
public interface UserMapper {
List getAllUsers();
User getUserById(Long userId);
void addUser(User user);
void updateUser(User user);
void deleteUser(Long userId);
}
实体类:
package com.lfsun.mockmvc.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private Long userId;
private String username;
private String email;
}
xml
INSERT INTO user (username, email)
VALUES (#{username}, #{email});
UPDATE user
SET username = #{username},
email = #{email}
WHERE user_id = #{userId};
DELETE
FROM user
WHERE user_id = #{userId};
配置
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/mockmvc?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=true
username: root
password: 123321
mybatis:
mapper-locations: classpath:/mapper/*.xml # 指定 MyBatis mapper 文件的位置
configuration:
map-underscore-to-camel-case: true # 配置驼峰命名规则
maven
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.7.14
com.lfsun
lfsun-study-mockmvc
0.0.1-SNAPSHOT
lfsun-study-mockmvc
lfsun-study-mockmvc
17
org.springframework.boot
spring-boot-starter
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-starter-web
org.projectlombok
lombok
provided
junit
junit
test
mysql
mysql-connector-java
8.0.23
compile
org.mybatis.spring.boot
mybatis-spring-boot-starter
1.3.2
org.springframework.boot
spring-boot-maven-plugin