单元测试-Mockito
常用注解
- @Mock: 创建一个Mock(可以是虚拟的)
- @Spy: 同上
- @InjectMocks: 会将带有 @Spy 和@Mock 注解的对象尝试注入到被测试的目标类中,一般的,加入 @Mock 注解的属性,都是加入 @InjetMocks 注解类的成员属性
场景
一般在测试spring boot服务时,不想因为测试一个 service 而启动整个 IOC 容器,如果项目比较大的话,这样将是无底洞的等待。。。
实战
Mockito+Junit测试
准备
在 spring boot 项目中
引入依赖:
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
<scope>test</scope>
</dependency>
开始
实体类 UserDo
:
@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserDo {
private Long id;
private String name;
private Integer age;
}
持久层 UserDao
:
@Repository
public class UserDao {
public UserDo loadByUserId(Long userId){
UserDo userDo = new UserDo();
userDo.setId(userId);
userDo.setName("tom");
userDo.setAge(32);
return userDo;
}
}
服务接口 UserService
:
public interface UserService {
UserDo loadByUserId(Long userId);
}
实现类 UserServiceImpl
:
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao;
@Override
public UserDo loadByUserId(Long userId) {
return userDao.loadByUserId(userId);
}
}
测试类:
import org.junit.Test; //不要引错了!!
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
@RunWith(MockitoJUnitRunner.class)
public class PureJavaMockTest {
@InjectMocks
private UserServiceImpl userService;
@Mock
private UserDao userDao;
@Test
public void loadUserTest() {
when(userDao.loadByUserId(any(Long.class)))
.thenReturn(new UserDo(2L, "jack", 45));
UserDo userDo = userService.loadByUserId(2L);
assertEquals("jack", userDo.getName());
}
}
如果不想写RunWith(MockitoJunitRunner.class)
,也可以这么写:
public class PureJavaMockTest {
@InjectMocks
private UserServiceImpl userService;
@Mock
private UserDao userDao;
@Before
public void initMocks(){
MockitoAnnotations.initMocks(this);
}
//....
}
执行测试用例,结果通过
注意:@Test 注解不要引错包了,之前一直引用 org.junit.jupiter.api.Test
下的,结果一起报 No Tests found !!
, 真是 >_> …