本来是想要查找关于junit 的知识,查找了依赖注入方式不同对junit测试也有影响。
正好备注下。
依赖注入三种方式:
字段注入(@Autowird)
优点:
操作简单
代码简洁缺点:
不支持不可变性:不能用final
容易出现依赖循环:程序刚启动时不报错
在单元测试中,很难替换依赖项
构造方法注入
优点:
不可变性:注入对象不可被修改
避免出现循环依赖
非IOC框架代码通用
缺点:
多依赖,代码阅读,维护困难
Setter 注入
---------------
Junit 测试
添加依赖
<!-- 包含了JUnit 5测试框架的核心API和注解-->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<scope>test</scope>
</dependency>
<!--Spring Boot提供的用于测试的启动器依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--提供参数化测试-->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<version>5.7.2</version>
<scope>test</scope>
</dependency>
快捷创建测试接口
以岗位信息接口为例:
鼠标右击->生成->测试->选择测试接口
在同模块下的测试工程快捷自动生成测试类
查看service层代码,考虑几个测试场景:
- 当数据库中不存在相同的岗位名称时,期望返回
UserConstants.UNIQUE
。- 当数据库中存在相同的岗位名称但是岗位ID与当前岗位ID不同,期望返回
UserConstants.NOT_UNIQUE
。- 当数据库中存在相同的岗位名称且岗位ID与当前岗位ID相同时,期望返回
UserConstants.UNIQUE
。
/**
* 校验岗位名称是否唯一
*
* @param post 岗位信息
* @return 结果
*/
@Override
public boolean checkPostNameUnique(SysPost post)
{
Long postId = StringUtils.isNull(post.getPostId()) ? -1L : post.getPostId();
SysPost info = postMapper.checkPostNameUnique(post.getPostName());
if (StringUtils.isNotNull(info) && info.getPostId().longValue() != postId.longValue())
{
return UserConstants.NOT_UNIQUE;
}
return UserConstants.UNIQUE;
}
编写测试代码
测试应遵循BDD三段式:given、when、then;即:假设xxx……那么当yyy时……应该会zzz。
package com.ruoyi.system.service.impl;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.system.domain.SysPost;
import com.ruoyi.system.mapper.SysPostMapper;
import org.junit.jupiter.api.Assertions;
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.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
public class SysPostServiceImplTest {
@Mock
private SysPostMapper postMapper;
@InjectMocks
private SysPostServiceImpl postService;
@BeforeEach
void setUp() {}
/**
* 当数据库中不存在相同的岗位名称时,应返回UNIQUE
*/
@Test
@DisplayName("NotExistingName")
public void testCheckPostNameUnique_NotExistingName() {
SysPost post = new SysPost();
post.setPostId(1L);
post.setPostName("Test Post");
when(postMapper.checkPostNameUnique("Test Post")).thenReturn(null);
Assertions.assertEquals(UserConstants.UNIQUE, postService.checkPostNameUnique(post));
}
/**
* 当数据库中存在相同的岗位名称但是岗位ID不同时,应返回NOT_UNIQUE
*/
@Test
@DisplayName("ExistingNameDifferentId")
public void testCheckPostNameUnique_ExistingNameDifferentId() {
SysPost existingPost = new SysPost();
existingPost.setPostId(2L);
existingPost.setPostName("Test Post");
SysPost post = new SysPost();
post.setPostId(1L);
post.setPostName("Test Post");
when(postMapper.checkPostNameUnique("Test Post")).thenReturn(existingPost);
Assertions.assertEquals(UserConstants.NOT_UNIQUE, postService.checkPostNameUnique(post));
}
/**
* 当数据库中存在相同的岗位名称且岗位ID相同时,应返回UNIQUE
*/
@Test
@DisplayName("ExistingNameSameId")
public void testCheckPostNameUnique_ExistingNameSameId() {
SysPost existingPost = new SysPost();
existingPost.setPostId(1L);
existingPost.setPostName("Test Post");
SysPost post = new SysPost();
post.setPostId(1L);
post.setPostName("Test Post");
when(postMapper.checkPostNameUnique("Test Post")).thenReturn(existingPost);
Assertions.assertEquals(UserConstants.UNIQUE, postService.checkPostNameUnique(post));
}
}
测试case
运行代码
测试成功后,右下角可以查看case的覆盖情况
左侧绿色表示测试覆盖成功,红色表示未测试或case覆盖不完全
右侧可查看测试类的覆盖率
生成测试报告
参数化测试
提供灵活的参数测试。
可以一个测试case灵活设置多个不同参数,表示不同参数。大大减少了测试代码量。
JUnit5参数化测试的几种方式-CSDN博客
@CsvSource
注解中的每一行代表一个测试用例。
第一个参数是岗位名称。
第二个参数的岗位id。
第三个参数是预期的唯一性状态。
@ParameterizedTest
@CsvSource({
"UniquePostName,1, true",
"ExistingPostName,2 ,false",
"UniquePostName,2, true"
})
@DisplayName("Should return correct uniqueness status")
public void testCheckPostNameUnique(ArgumentsAccessor arguments) {
String postName = arguments.getString(0);
Long postId = arguments.getLong(1);
boolean expectedStatus = arguments.getBoolean(2);
// 模拟postMapper的行为
if ("UniquePostName".equals(postName)) {
when(postMapper.checkPostNameUnique(postName)).thenReturn(null);
} else if ("ExistingPostName".equals(postName)) {
SysPost existingPost = new SysPost();
existingPost.setPostId(1L);
when(postMapper.checkPostNameUnique("ExistingPostName")).thenReturn(existingPost);
} else {
when(postMapper.checkPostNameUnique(null)).thenReturn(null);
}
SysPost post = new SysPost();
post.setPostName(postName);
post.setPostId(postId);
assertEquals(expectedStatus, postService.checkPostNameUnique(post));
}
实现一个case满足三种情况