本文是自己学习的一个总结
我自己的理解是,单元测试就是面向函数的一个测试。这种测试只是针对函数内的逻辑进行测试。如果这个函数依赖了外界,那么单元测试是应该要屏蔽掉外界的影响的。
比如web开发中,service层中有一个方法用来用来插入数据。
public class Service implements ServiceImpl {
/**
* 这就是service中一个普通的方法,但它在执行过程中会依赖外部资源。
*/
@Override
public void insertData(Data data) {
//dao是已经注入的实例化对象,dao.insertData()方法插入成功返回true,插入失败返回false。
if(dao.insertData(data)) {
//如果插入成功,执行一些操作
} else {
//如果插入失败,执行其他操作
}
}
}
对于上面的这个方法,我们要对它单元测试的话,测试的范围应该只限于insertData()这个方法的逻辑,即验证插入成功后的逻辑和插入失败后的逻辑。
我们不应该让测试逻辑去真正执行依赖的dao层方法。主要有以下两点原因
Mockito是个用来单元测试的框架。它给我们提供了很多方便的工具来单元测试。
上面提到单元测试中,如果方法逻辑依赖到了外部对象,那在测试时我们应该模拟外部对象的行为,让测试的逻辑不去真正执行外部对象的方法。
但真正模拟的时候困难重重。但如果我们使用Mockito框架的话,可以通过简单的注解和一些方法轻松达到模拟的效果。我们可以先看看Mockito的一个使用示例。
/**
* 这是测试类
*/
public class StudentServiceTest {
/**
* 先不要管这个方法在干什么
*/
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
}
/**
* 这里可以先理解成生成了一个实例对象。StudentServiceTest测试类就是想对这个类中的方法进行单元测试
*/
@InjectMocks
private StudentService studentService;
/**
* 这个是studentService会依赖的外部对象,@Mock注解相当于模拟出这个类的一个实例,
* 然后注入到@InjectMocks标记的成员中(即studentService)。
* 现在可以简单地看成Spring中的@Autowired注解。
*/
@Mock
private StudentDao studentDao;
/**
* @Test标注的方法就是测试方法,从方法名上看,这是对StudentService的insertData方法做单元测试
*/
@Test
public void insertDataTest() {
Data data = new Data();
//省略对data赋值的操作
//设置,如果执行到StudentDao中的insertData方法,就返回true。简单一句话达到模拟效果
Mockito.when(studentDao.insertData(Mockito.any()).thenReturn(true);
//执行studentService的insertData方法时,遇到StudentDao中的insertData方法,就会返回true,
//这样我们就可以测试插入成功的逻辑了
studentService.insertData(data);
}
}
从上面的例子可以看出,Mockito框架提供的一些方法和注解,能让我们很方便地进行单元测试。
以下的maven依赖可以直接搜索Maven Mockito得到,注意版本号不要太高,不然项目的Java版本需要8以上的版本才支持。
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>2.23.4</version>
<scope>test</scope>
</dependency>
因为Mockito是在传统的测试上运行的,所以也要加上Junit的maven。
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
我们可以通过白名单(黑名单),配置正则表达式,规定哪些类需要测试,哪些类不需要测试。
在plugn中引入org.apache.maven.plugins。然后在其configuration标签中设置excludes(黑名单)或includes(白名单)。
下面的表示项目启动时,不要对二级目录名称为manual的类测试。
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<excludes>
<exclude>**/manual/**/*.java</exclude>
</excludes>
</configuration>
</plugin>
配置完这些以后,可以开始写Mockito单元测试了。我记录了一个简单的入门,可以看看这篇文章https://blog.csdn.net/sinat_38393872/article/details/106539895。