单元测试-mockito

这篇具有很好参考价值的文章主要介绍了单元测试-mockito。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

mockito介绍

mock作用

在单元测试中,对于一个类中的方法,常常需要依赖其他类的方法、操作数据dto等对象实例。

  1. 方法mock:依赖的方法又可能依赖其他方法,呈现级联的树状结构。

    1. 问题:在一些情况下,这个依赖树会很深,其中依赖的一个子方法一旦修改出现问题,如果引起大量的单测不可用,对于问题的定位而言十分困难,而且也失去了单元测试的最小单元化、只测试当前逻辑功能的意义。因此在单元测试中,对依赖的子方法逻辑功能的隔离是十分重要的;
    2. mock解决方案:通过对操作对象dto进行mock、调用子方法时进行代理跳过具体的执行逻辑直接对执行结果进行模拟,实现对子方法和当前参数处理的模拟运行。
  2. 操作数据mock:执行逻辑对于不同case的处理数据,可能有不同的分支逻辑进行处理;

    1. 问题:如果不能覆盖所有分支,对于上线后千奇百怪的实际用户操作产生的数据,存在踩坑、不可用的风险。
    2. mock解决方案:理由mock构造不同的数据,作为入参、方法调用结果进行各分支的测试。

因此在单元测试中mock技术是其核心功能。

mockito竞品

EasyMock(https://easymock.org/)、
JMock(http://jmock.org/)、
PowerMock(https://github.com/powermock/powermock)

mockito使用

引入依赖

引入mockito-core依赖

<dependency>
  <groupId>org.mockito</groupId>
  <artifactId>mockito-core</artifactId>
  <version>2.7.19</version>
  <scope>test</scope>
</dependency>

mockito只关注mock,还需要依赖junit进行单测。

<dependency>
  <groupId>junit</groupId>
  <artifactId>junit</artifactId>
  <version>4.12</version>
  <scope>test</scope>
</dependency>

在单测类上注入使用mockito

以下是一个springboot的mock例子,使用@MockBean进行bean的mock和注入,在处理逻辑中利用Mockito.when(xxx).thenReturn(xxx)对调用方法进行mock,实现内部依赖方法调用的mock解耦,实现单元测试只关注当前待测试方法的目标。

@RunWith(SpringRunner.class)
@SpringBootTest
publicclass UserServiceTest {
    
    @Autowired
    private UserService userService;
    
    /* mock生成代理 */
    @MockBean
    private UserDao userDao;
 
    @Test
    public void getUserById() throws Exception {
        // 定义当调用mock userDao的getUserById()方法,并且参数为3时,就返回id为200、name为I'm mock3的user对象
        Mockito.when(userDao.getUserById(3)).thenReturn(new User(200, "I'm mock 3"));
        
        // 返回的会是名字为I'm mock 3的user对象
        User user = userService.getUserById(1);
 
        Assert.assertNotNull(user);
        Assert.assertEquals(user.getId(), new Integer(200));
        Assert.assertEquals(user.getName(), "I'm mock 3");
    }
}

使用doAnswer实现mock调用结果

public class MockitoAnswerTest {
  @InjectMocks
  private TestClass testClass;
  @Mock
  private CalledClass calledClasee;

  @Test
  public void analysisTest() {
    MockitoAnnotations.openMocks(this);
    Mockito.doAnswer(new Answer<String>() {
      @Override
      public String answer(InvocationOnMock invocation) throws Throwable {
        return "mocked answer";
      }
    }).when(calledClasee).call(Mockito.any());
    String result =
        testClass.test(new Object());
    Assert.assertEquals("mocked answer", result);
  }

Mockito 的限制

上述就是 Mockito 的 mock 对象使用方法,不过当使用 Mockito 在 mock 对象时,有一些限制需要遵守
1. 不能 mock 静态方法
2. 不能 mock private 方法
3. 不能 mock final class

mockito实现-源码分析

加载初始化mockito

在单元测试的启动阶段开启mockito注解,传递当前测试实例。

@Before
public void setUp() {
    MockitoAnnotations.openMocks(this);
}
openMock源码

openMocks方法会对当前单元测试类中的各字段field,通过

/**
     * Initializes objects annotated with Mockito annotations for given testClass:
     *  &#064;{@link org.mockito.Mock}, &#064;{@link Spy}, &#064;{@link Captor}, &#064;{@link InjectMocks}
     * <p>
     * See examples in javadoc for {@link MockitoAnnotations} class.
     *
     * @return A closable to close when completing any tests in {@code testClass}.
     */
    public static AutoCloseable openMocks(Object testClass) {
        if (testClass == null) {
            throw new MockitoException(
                    "testClass cannot be null. For info how to use @Mock annotations see examples in javadoc for MockitoAnnotations class");
        }

        AnnotationEngine annotationEngine =
                new GlobalConfiguration().tryGetPluginAnnotationEngine();
        return annotationEngine.process(testClass.getClass(), testClass);
    }

AnnotationEngine有3个实现类,IndependentAnnotationEngine(处理)、SpyAnnotationEngine(处理@Spy注解)、InjectingAnnotationEngine(组装代理IndependentAnnotationEngine和SpyAnnotationEngine)

单元测试-mockito,测试,单元测试,测试工具单元测试-mockito,测试,单元测试,测试工具

ScopedMock用来管理mock对象的生命周期,mock对象在threadLocal中维护,当单测退出时,清空当前线程(单测一般是单线程的)threadLocal中的mock出来的对象进行回收处理。具体逻辑查看org.mockito.internal.creation.bytebuddy.InlineByteBuddyMockMaker类。

@Mock标注字段的对象代理

@Mock标注的单元测试对象中filed对象的创建是由上面的openMock中对@Mock注解处理时createMockFor(annotation,field)触发的。

实现逻辑如下。
单元测试-mockito,测试,单元测试,测试工具
单元测试-mockito,测试,单元测试,测试工具

org.mockito.internal.creation.bytebuddy.InlineByteBuddyMockMaker中newInstance()创建对象实例方法如下。

单元测试-mockito,测试,单元测试,测试工具
单元测试-mockito,测试,单元测试,测试工具

调用构造函数实例化mock对象时,参数列表如果是基础类型则传0(false)、对象类型传null
单元测试-mockito,测试,单元测试,测试工具

最终用constructor.newInstance(arguments)反射等方式将对象创建出来。
单元测试-mockito,测试,单元测试,测试工具文章来源地址https://www.toymoban.com/news/detail-847665.html

参考资料

  1. 万字长文:一文详解单元测试干了什么 https://mp.weixin.qq.com/s/9_TQbVSl1CQLQzuUrsrHLQ
  2. Java单元测试Mock框架Mockito入门介绍 https://cloud.tencent.com/developer/article/1850562
  3. Mock工具之Mockito实战 https://zhuanlan.zhihu.com/p/580113391

到了这里,关于单元测试-mockito的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 单元测试工具——JUnit的使用

    ⭐️ 前言 ⭐️ 本篇文章主要介绍单元测试工具JUnit的使用。 🍉 欢迎点赞 👍 收藏 ⭐ 留言评论 📝 私信必回哟 😁 🍉 博主将持续更新学习记录收获,友友们有任何问题可以在评论区留言 🍉 博客中涉及源码及博主日常练习代码均已上传GitHub JUnit提供了非常强大的注解功能

    2024年02月02日
    浏览(46)
  • Tessy — 嵌入式软件单元测试/ 集成测试工具学习

    Tessy — 嵌入式软件单元测试/ 集成测试工具 本文章向大家介绍Tessy — 嵌入式软件单元测试/ 集成测试工具,主要包括Tessy — 嵌入式软件单元测试/ 集成测试工具使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。 Tessy 源

    2024年02月04日
    浏览(68)
  • 嵌入式单元测试工具Tessy的一些测试技巧

    最近做了一个平台项目,需要进行动态代码测试,入门了嵌入式单元测试工具Tessy,总结了一些简单的测试技巧。 当前网上的教程普遍只写内容概要,真正入手还得自己认真摸索一番。为此,特意总结了一些Tessy测试技巧以供有缘人参考。 提几个Tessy工具使用的问题。 1.如何

    2023年04月17日
    浏览(61)
  • 单元测试自动生成工具Evosuite的安装使用

    1.1介绍 官网: https://www.evosuite.org/ GitHub: https://github.com/EvoSuite 1.2安装插件 (1)直接安装 进入settigs中,点击plugins,搜索Evosuite,点击安装 (2)从官网下载安装 打开网页 https://plugins.jetbrains.com/plugin/18956-evosuite-xenoamess-tpm-/versions ,点击Download按钮下载插件。 选择菜单File

    2024年02月03日
    浏览(50)
  • copilot 产生 python工具函数并生成单元测试

    stock.py 这个文件,我只写了注释(的开头),大部分注释内容和函数都是copilot 再新建一个 stock_test.py,写一行注释,Ctrl+L(或者调用 Open compiletion Panel)产生了很多的单元测试样例。 再装一个 Python Test Explorer 插件用来进行 GUI test 附上我的 python test gui 配置 .vscode/settings.jon 有了

    2024年02月04日
    浏览(43)
  • Java单元测试AI工具-Diffblue Cover

    什么是Diffblue? Diffblue是一款基于人工智能和机器学习技术的自动化测试工具。它可以帮助开发人员快速、准确地发现代码中的错误和漏洞,并生成相应的测试用例。Diffblue的核心技术是人工智能和机器学习,它可以自动地分析代码,理解代码逻辑,并生成相应的测试用例。

    2024年02月08日
    浏览(39)
  • 【Python百宝箱】Python测试工具大揭秘:从单元测试到Web自动化

    在现代软件开发中,测试是确保代码质量和稳定性的关键步骤。Python作为一门广泛应用的编程语言,拥有丰富的测试工具和库,从单元测试到Web自动化,覆盖了多个测试层面。本文将介绍一系列Python测试工具,帮助开发者选择适合项目需求的工具,提高代码的可靠性和可维护

    2024年02月03日
    浏览(52)
  • 单元测试探析:什么是Stubs、Mocks、Spies、Dummies?带你了解4个核心工具

    在单元测试中,对象之间的依赖往往交织到一起,需要拆成各个单元才能逐个击破,这也是单元测试的目的。如何将这些交织到一起的对象拆开,需要一些工具,这些工具业内人们称其为“测试替身”。 本文作者介绍了单元测试中的4个“测试替身”工具,即Stubs、Mocks,、Sp

    2024年02月16日
    浏览(38)
  • 【单元测试】Mockito使用详解

    一个单元测试应该有如下特点: 应该是自动化的 应该可以快速运行 每个单元测试不应该依赖其它测试的结果和执行顺序,单元测试框架可以按任意的顺序执行每个测试 每个单元测试不应该依赖数据库,外部文件,或者任何长时间运行的任务。单元测试应该是独立的,不应该

    2024年04月15日
    浏览(87)
  • 单元测试与Mockito

    系列文章目录和关于我 最近在新公司第一次上手写代码,写了一个不是很难的业务逻辑代码,但是在我写单元测试的时候,发现自己对单元测试的理解的就是一坨,整个过程写得慢,还写得臭。造成这种局面我认为是因为: 对Mockito api是不是很熟悉 没有自己单元测试方法论

    2023年04月22日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包