关于单测技术选型,聊聊我的思考

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

对于单测来说,目前常用的单测框架有:

  • JUnit
  • Mockito
  • Spock
  • PowerMock
  • JMockit
  • TestableMock

其中 JUnit 不支持 Mock,因此基本不会只用 JUnit,而是结合其他有 Mock 功能的框架一起使用。从知名度及使用率来说,Mockito 和 Spock 使用较多,而 PowerMock、JMockit、TestableMock 使用较少。下面我们将主要对比 Mockito 和 Spock 两种框架的差异。

Mockito

Mockito 是 Java 单元测试中的 Mock 框架,一般都是与 JUnit 一起使用。Mockito 功能强大,几乎所有你能想到的功能都支持,并且由于发布时间较长,因此使用的人非常多。

  • 优点:功能强大、使用人数多、资料丰富。
  • 缺点:代码不够简洁、没有统一的单测结构、不支持静态方法和私有方法 Mock。

更多信息详见官网:https://site.mockito.org/

Spock

Spock 是一个企业级的测试规范框架,可用来测试 Java 和 Groovy 应用。Spock 最大的特色是其简洁美观的语言规范。Spock 兼容绝大多数 IDE、编译工具和 CI 集成服务器。Spock 框架使用 Groovy 语言编写,而 Groovy 语言则是 Java 语言的超集,绝大多数 Java 语言语法在 Groovy 中都支持。

  • 优点:单测结构统一、代码简洁、异常测试及参数测试支持更好。
  • 缺点:学习成本略高、不支持静态方法和私有方法 Mock。

更多信息详见官网:https://spockframework.org/

Mockito vs Spock

在 Spock vs JUnit 5 - the ultimate feature comparison 中详细对比了 Mokito 与 Spock 的差异,他们在发展情况、学习曲线、工具支持等方面的比较如下图所示。

从上图可以看到,Mockito 框架在发展、学习曲线、工具支持、从 JUnit4 迁移几方面比较有优势。而 Spock 框架则在测试结构、异常测试、条件测试等方面比较有优势。因此,选择哪个测试框架完全基于实际情况。例如,如果你目前的情况是:

  1. Java 是唯一的语言。
  2. 想要更强的编译时错误检查。
  3. 更稳定、更主流的实现方式。

那么选择 JUnit + Mockito 的方式是更好的选择。但如果你目前的情况是:

  1. 希望单测跟简单易读
  2. 更简洁的参数测试与异常测试

那么选择 Spock 会是更好的选择。

为啥选择 Spock?

根据前面的分析,Mockito 的主要优势在于比较稳定、主流,缺点在于不够简洁易读。而 Spock 虽然使用人群没有 Mockito 那么多,但国内也有一些大厂在使用 Spock,例如美团等(可参考:Spock单元测试框架介绍以及在美团优选的实践)。

我们重视写单测,但是又不希望写单测花费太多时间,毕竟业务才是第一位的。因此,我们希望单测代码尽可能简洁、可维护。 基于这个原因,我们选择了 Spock 框架作为后端的单测框架解决方案。而 Spock 不支持 static 方法及 private 方法 Mock 的缺陷,则尝试通过整合 PowerMock 或 TestableMock 来解决。

可维护性更强

在极客时间《程序员的测试课》中,有一节关于讲了一个好的自动化测试长什么样?在这里面,作者提到一个好的单测应该由 准备、执行、断言、清理 4 个阶段组成。

对于 Mockito 而言,它并没有规定具体的代码规范,因此只能依靠注释来标注哪些代码是准备阶段的代码,哪些是执行阶段的代码,哪些是断言阶段的代码,如下代码所示。

class SimpleCalculatorTest {
    @Test
    void shouldAddTwoNumbers() {
        //given 准备
        Calculator calculator = new Calculator();
        //when 执行
        int result = calculator.add(1, 2);
        //then 断言
        assertEquals(3, result);
    }
}

对于 Spock 而言,其通过 given-when-then 的结构,强制要求编写者将不同阶段的代码放到不同的位置,从而增强了可读性。同样是用于测试计算器的加法函数的单测用例,使用 Spock 框架编写的单测如下代码所示。

class SimpleCalculatorSpec extends Specification {
    def "should add two numbers"() {
        given: "create a calculater instance"
            Calculator calculator = new Calculator()
        when: "get calculating result via the calculater"
            int result = calculator.add(1, 2)
        then: "assert the result is right"
            result == 3
    }
}

可以看到,通过 given-when-then 结构的划分,我们可以更加快速地弄清楚单测的内容,从而提高单测的可读性,使得单测更加容易维护。

代码更加简洁

对于 Mockito 与 Spock 而言,它们之间的一个很大的差别是:Spock 的代码更加简洁。这个特性可以让我们编写比 Mockito 更少的代码,从而实现同样的功能。例如在 Mockito 中,我们 Mock 某个接口实现时,通常需要写一长串的 give(...).return(...) 代码。而在进行断言的时候,也需要写比较长的 then(xx).should(xx).checkxx() 代码,如下图所示。

@Test
public void should_not_call_remote_service_if_found_in_cache() {
    //given
    given(cacheMock.getCachedOperator(CACHED_MOBILE_NUMBER)).willReturn(Optional.of(PLUS));
    //when
    service.checkOperator(CACHED_MOBILE_NUMBER);
    //then
    then(webserviceMock).should(never()).checkOperator(CACHED_MOBILE_NUMBER);
    verify(webserviceMock, never()).checkOperator(CACHED_MOBILE_NUMBER);  
}

但在 Spock 中的代码就相对比较简洁,如下所示代码实现了上述 Mockito 代码同样的功能。

def "should not hit remote service if found in cache"() {
    given:
        cacheMock.getCachedOperator(CACHED_MOBILE_NUMBER) >> Optional.of(PLUS)
    when:
        service.checkOperator(CACHED_MOBILE_NUMBER)
    then:
        0 * webserviceMock.checkOperator(CACHED_MOBILE_NUMBER)
}

可以看到,Spock 没有 given、willReturn 等关键词,而是取而用 >> 等符号来实现,这样代码更加简洁,阅读起来也更加明了。

案例代码对比:https://www.yuque.com/lugew/spock/wkxhvk文章来源地址https://www.toymoban.com/news/detail-410820.html

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

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

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

相关文章

  • 【思考】聊聊低代码的实践之路

    这个概念由来已久,但是在国内兴起,是最近几年; 低代码即Low-Code; 指提供可视化开发环境,可以用来创建和管理软件应用; 简单的说 就是可以通过各种组件的拖拽,实现页面的创建,交互流程和逻辑,以及数据层面的管理,更加高效的实现需求; 早先在数据公司时;见

    2024年02月01日
    浏览(46)
  • Flink/Doris生产环境方案选型的一些思考

    各位总监,技术负责人,架构师们大家好。今天的文章有点短,是一些个人思考,仅做记录。 以Flink为主的计算组件和以Doris为代表的存储+计算一体的方案选择问题是我们在技术选型过程中最常见的问题之一。也是很多公司和业务支持过程中会遇到的问题。 这个问题非常「实

    2024年02月02日
    浏览(46)
  • 【深度思考】聊聊CGLIB动态代理原理

    CGLIB的全称是:Code Generation Library。 CGLIB是一个强大的、高性能、高质量的代码生成类库,它可以在运行期扩展Java类与实现Java接口, 底层使用的是字节码处理框架ASM。 Github地址:https://github.com/cglib/cglib。 CGLIB的Maven坐标如下所示: 首先,新增一个类: 然后,自定义一个方法

    2023年04月21日
    浏览(35)
  • 聊聊多模态大模型处理的思考

    转载请注明出处:https://www.cnblogs.com/zhiyong-ITNote 多模态:文本、音频、视频、图像等多形态的展现形式。 目前部门内业务要求领域大模型需要是多模态——支持音频/文本。从个人思考的角度来审视下,审视下多模态大模型的实现方式。 首先就要区分输入与输出,即输入的模

    2024年03月26日
    浏览(51)
  • 【深度思考】聊聊JDK动态代理原理

    首先,定义一个接口: 然后,新增一个类并实现上面的接口: 假设现在有这么一个需求:在不改动以上类代码的前提下,对该方法增加一些前置操作或者后置操作。 接下来就来讲解下,如何使用 JDK动态代理 来实现这个需求。 首先,自定义一个调用处理器,实现 java.lang.r

    2023年04月17日
    浏览(39)
  • 聊聊大模型微调训练全流程的思考

    转载请注明出处:https://www.cnblogs.com/zhiyong-ITNote 参考现有的中文医疗模型:MedicalGPT、CareGPT等领域模型的训练流程,结合ChatGPT的训练流程,总结如下: 在预训练阶段,模型会从大量无标注文本数据集中学习领域/通用知识;其次使用{有监督微调}(SFT)优化模型以更好地遵守特定

    2024年03月18日
    浏览(46)
  • 聊聊心理医疗领域大模型的落地思考

    转载请注明出处:https://www.cnblogs.com/zhiyong-ITNote 近来,工作偏向于心理医疗领域方面的大模型,仅从领域大模型的落地,聊聊个人的一些思考。 准备好花钱买GPU。 首先需要审视斟酌业务领域的特殊性与可行性,我们要做的是心理领域,而心理领域倾向于医患对话,即 询问链

    2024年03月21日
    浏览(47)
  • 聊聊我的故事-悲惨的童年

    本人是06年生的,快18了, 提示:以下是本篇文章正文内容,下面案例可供参考 本人已经17了,在这17年过的很悲惨,也许我的性格就这样了,阴阳怪气的,好学 我出生在河北省唐山市,那时的我很招人喜欢,呆萌呆萌的 我比较淘气,我隐隐约约记得我把教师后面架子上的玩

    2024年02月14日
    浏览(34)
  • 我的NPI项目之Android Camera (一) -- Camera选型

    在一个项目起草PRS的时候就应该定义Camera的硬件参数,例如接口类型,分辨率,PDAF,OIS等等。在正式进行Camera选型的时候,还要考虑到是国产还是日韩,美国的模块。生命周期,后期服务等等因素。 目前在高通4490平台上,硬件上是支持有三路CSI, 并且能够支持如下的camer

    2024年02月19日
    浏览(40)
  • 对于现有的分布式id发号器的思考 id生成器 雪花算法 uuid

    目录 雪花id tinyid uuid 分布式id特点 业务编号 数据中心编号 当前时间 ip地址 当前序号 对于时钟回拨问题 发号器机器当期时间小于redis的时间 解决步骤 发号器机器当期时间等于redis时间 发号器机器当期时间大于redis最大的时间(相关的key不存在) 分布式id的单次获取和批次获

    2024年02月13日
    浏览(52)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包