单元测试中Mock依赖解耦

单元测试的思路就是我们想在不涉及依赖关系的情况下测试代码。

在单元测试中,我们往往想去独立地去测一个类中的某个方法,但是这个类可不是独立的,它会去调用一些其它类的方法和service,这也就导致了以下两个问题:

  • 外部服务可能无法在单元测试的环境中正常工作,因为它们可能需要访问数据库或者调用其它Http服务。
  • 我们的测试关注点在于这个类的实现上,外部类的一些行为可能会影响到我们对本类的测试,那也就失去了我们进行单测的意义。

解决方案是将依赖mock掉,也即在测试过程中,对那些不容易构建的对象,用一个虚拟对象来代替测试的情形。

添加依赖

  1. <dependency>
  2. <groupId>org.mockito</groupId>
  3. <artifactId>mockito-core</artifactId>
  4. <version>2.0.111-beta</version>
  5. </dependency>

被测试的ServiceImpl

  1. /**
  2. * 融合事件表 服务实现类
  3. *
  4. * @author BladeX
  5. * @since 2021-07-05
  6. */
  7. @Service
  8. public class MergeEventServiceImpl extends ServiceImpl<MergeEventMapper, MergeEvent> implements IMergeEventService {
  9. /**
  10. * 获取攻击链
  11. *
  12. * @param startTime 开始时间
  13. * @param endTime 结束时间
  14. * @param ip 核心ip
  15. * @param isSrc 核心ip是否作为源ip
  16. * @param depth 探测深度
  17. * @return 攻击链节点和攻击链边
  18. */
  19. @Override
  20. public R<Map<String, Object>> attackChain(String startTime, String endTime, String ip, boolean isSrc, int depth) {
  21. // 实现略
  22. }
  23. }

生成测试类

  1. 测试包和源码包的关系

image.png

  1. 使用IDEA生成工具生成测试类

image.png
image.png
填写源包就可以,会在test目录下生成相同的包,记住勾选方法!

  1. class MergeEventServiceImplTest {
  2. @Test
  3. void attackChain() {
  4. }
  5. }

启动——标注Mock类

  1. @RunWith(MockitoJUnitRunner.class)
  2. class MergeEventServiceImplTest {
  3. @Test
  4. void attackChain() {
  5. }
  6. }

其中RunWihth是JUnit5的注解,MockitoJUnitRunner是Mockito的类