Spring Boot 单元测试笔记
1. 导入JUnit5测试框架
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.8.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-launcher</artifactId>
<version>1.8.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<version>5.7.2</version>
<scope>test</scope>
</dependency>
其他按 Spring Boot 项目标准,按需引入即可
2. 编写Service
/**
* 假设一个订单类
*/
public class DemoOrder {
private String orderId;
private String orderUser;
private String contents;
private Integer quantity;
private BigDecimal price;
private BigDecimal total;
// getter,setter略
}
Mapper 接口
@Mapper
public interface DemoOrderMapper {
DemoOrder selectOrderByOrderId(String orderId);
List<DemoOrder> selectOrderByOrderParam(OrderParam param);
}
Service
/**
* DemoService
* 此处的两个方法,一个是传入String,一个是传入封装好的参数类 OrderParam。这两种方法的测试方法不同
*/
public interface DemoService {
DemoOrder findOrderByOrderId(String orderId);
DemoOrder findOrderByRequestParam(OrderParam param);
}
@Service
public class DemoServiceImpl implements DemoService {
@Autowired
DemoMapper demoMapper;
@Override
public DemoOrder findOrderByOrderId(String orderId) {
DemoOrder order = demoMapper.selectOrderByOrderId(orderId);
return order;
}
@Override
public DemoOrder findOrderByRequestParam(OrderParam param) {
List<DemoOrder> orderList = demoMapper.selectOrderByRequestParam(param);
return CollectionUtils.isEmpty(orderList) ? null : orderList.get(0);
}
}
3. 编写测试类
@DisplayName("单元测试用例")
public class DemoServiceTest {
@InjectMocks
DemoServiceImpl demoService; // 此处注意要使用Service接口的实现类
@Mock
DemoMapper demoMapper; // 对Mapper使用Mock
@BeforeEach
public void setUp() {
openMocks(this);
// 老版本是 initMocks(this);
// 准备数据
DemoOrder order1 = new DemoOrder();
order1.setOrderId("001");
order1.setOrderUser("User1");
order1.setContents("contents1");
order1.setQuantity(1);
order1.setPrice(new BigDecimal("10.5"));
order1.setTotal(new BigDecimal("10.5"));
DemoOrder order2 = new DemoOrder();
order2.setOrderId("002");
// ... 其他属性略
DemoOrder order3 = new DemoOrder();
order3.setOrderId("003");
// ... 其他属性略
// 以下为mock mapper的方法模拟
// 1. 传String的方法,直接传入模拟的参数即可
when(demoMapper.selectOrderByOrderId("001")).thenReturn(order1);
when(demoMapper.selectOrderByOrderId("002")).thenReturn(order2);
// ...
// 2. 传OrderParam的方法,需要将 when...thenReturn语法改为 doReturn...when... 语法
doReturn(Collections.singletonList(order1))
.when(demoMapper).selectOrderByOrderParam(argThat(
new ArgumentMatcher<OrderParam>() {
@Override
public boolean match(OrderParam param) {
return param.getOrderId().equals("001")
}
}
));
// 此处也可以将 ArgumentMatcher 单独定义
doReturn(Collections.singletonList(order2))
.when(demoMapper).selectOrderByOrderParam(argThat(
new ArgumentMatcher<OrderParam>() {
@Override
public boolean match(OrderParam param) {
return param.getOrderId().equals("002")
}
}
));
}
@Test
public void findOrderByOrderIdTest() {
String orderId = "001";
DemoOrder order = demoService.findOrderByOrderId(orderId);
assertThat(order.getOrderUser()).isEqualTo("User1");
}
@Test
public void findOrderByOrderParamTest() {
OrderParam param = new OrderParam();
param.setOrderId("002");
DemoOrder order = demoService.findOrderByOrderParam(param);
assertThat(order.getOrderUser()).isEqualTo("User2");
}
}