摘要:本文主要介绍如何使用junit
来编写单元测试,包含mock
对象的方法和mock
静态方法使用案例,提高开发效率。
pom.xml
引入依赖包
springboot
引入依赖包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
<scope>test</scope>
</dependency>
普通java
项目
<!-- junit5 -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.9.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<version>5.9.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>4.11.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<version>4.11.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
<version>4.11.0</version>
<scope>test</scope>
</dependency>
定义的类
UserEntity
@Data
@TableName("user")
public class UserEntity {
@TableId
private String id;
private String name;
private String address;
private Date createTime;
}
UserUtils
作为被
mock
的静态类
public class UserUtils {
public static UserEntity getUser(){
return new UserEntity();
}
public static boolean checkName(String name){
UserEntity userEntity = getUser();
return userEntity.getName().equals(name);
}
}
UserService
mock
的测试类
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
@SDS("dynamic_member")
@Transactional(rollbackFor = Exception.class)
public UserEntity add(UserEntity userEntity) throws Exception{
userEntity.setId(IdWorker.getIdStr());
userEntity.setCreateTime(new Date());
userMapper.insert(userEntity);
return userEntity;
}
public UserEntity getLoginUser(){
return UserUtils.getUser();
}
public boolean checkName(String name){
boolean result = UserUtils.checkName(name);
System.out.println(result);
return result;
}
}
单元测试
UserServiceTest
@ExtendWith(MockitoExtension.class)
class UserServiceTest {
/** mock静态类 */
private static MockedStatic<UserUtils> userUtils;
/** mock被测试的类 */
@InjectMocks
private UserService userService;
/** mock注入的类 */
@Mock
private UserMapper userMapper;
@BeforeAll
static void init(){
userUtils = Mockito.mockStatic(UserUtils.class);
}
@Test
void add() throws Exception {
// mock方法中调用的其他方法
Mockito.when(userMapper.insert(Mockito.any())).thenReturn(1);
UserEntity result = userService.add(new UserEntity());
assertNotNull(result.getId());
}
@Test
void getLoginUser() {
UserEntity userEntity = new UserEntity();
userEntity.setName("zhangsan");
// mock无参静态方法
userUtils.when(UserUtils::getUser).thenReturn(userEntity);
UserEntity result = userService.getLoginUser();
assertEquals("zhangsan",result.getName());
}
@Test
void checkName() {
// mock有参数静态方法
userUtils.when(() -> UserUtils.checkName(Mockito.anyString())).thenReturn(true);
boolean result = userService.checkName("zhangsan");
assertTrue(result);
// mock有参数静态方法
userUtils.when(() -> UserUtils.checkName(Mockito.anyString())).thenReturn(false);
result = userService.checkName("zhangsan");
assertFalse(result);
}
}
测试结果
符合我们得预期结果
使用SpringBoot
上下文的单元测试
为什么要使用
SpringBoot
上下文来测试呢,因为有时候我们需要查询数据库数据,或者测试我们的SQL
语句是否正确,我们就需要快速启动Spring
来进行验证,这里使用单元测试能更快保证我们的开发速度
使用的注解
@ExtendWith
扩展用于申明是什么类型的单元测试,使用
@ExtendWith(SpringExtension.class)
@SpringBootTest
该类用于启动
SpringBoot
的上下文
- 如果直接使用
@SpringBootTest
则会从该类的包从下往上找到SpringBoot
的启动类,直接启动全部的模块,速度比较慢 - 推荐使用
@SpringBootTest(classes = Sample2Test.class)
,使用自己当前的测试类作为启动类
@ComponentScan
需要扫描的包,我们需要什么包就扫描什么包
@Import
我们需要
Spring
管理的Bean
,可以通过这种方式引入,也可以通过上面的包扫描
@ImportAutoConfiguration
导入自动装配,比如
rabbitmq
,@ImportAutoConfiguration(value = {RabbitAutoConfiguration.class})
,总之我们需要什么引入什么
@ActiveProfiles("default")
指定单元测试的
xxx.yml
配置文件
完整案例
@ExtendWith(SpringExtension.class)
@SpringBootTest(classes = Sample2Test.class)
@ComponentScan(value = {"com.huzhihui.rabbitmq.demo.sample"})
@Import(value = {SampleProducer.class})
@ImportAutoConfiguration(value = {RabbitAutoConfiguration.class})
@ActiveProfiles("default")
public class Sample2Test {
@Autowired
private SampleProducer sampleProducer;
@Test
void testSend() {
sampleProducer.send("测试2,不要相互影响");
}
}