• Spring Boot 中单元测试框架 Mockito 的正确使用


    Spring Boot 中单元测试框架 Mockito 的正确使用

    本文是对前段时间修复老项目单元测试的总结记录,在修复过程中,发现中文互联网中的不少文章对单元测试框架Mockito的使用说明基本不准确又或是AI生成,希望我这篇能够把这方面简单说透说对。
    文章最后给到一个比较规矩的单元测试示例,基本的单元测试对照着写足够用。

    下文主要提及如下框架:

    1. Spring Boot
    2. Mockito
    3. PowerMock

    文章也可移步至 AllinProgram.com 查看。

    Spring Boot编写单元测试

    若只是希望使用Junit编写比较简单的单元测试,建议直接引入Spring Boot官方的测试依赖spring-boot-starter-test,其内置了版本兼容的JunitMockito,开箱即用。

    <dependency>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-testartifactId>
        <scope>testscope>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    如何Mock静态方法

    上文提到 spring-boot-starter-test已经引入 Mockito,方便你对 Bean进行Mock,但是你可能会发现其无法针对静态方法进行Mock。

    此时,你可以检查下其引入的 Mockito的具体版本,因为不同版本在Mock静态方法时的操作是不一样的。

    主要可以分为Mockito的版本是否小于v3.0.0。

    Mockito的版本小于v3.0.0

    需要配合 PowerMock使用以支持Mock静态方法!!!

    • 其版本对应关系可以查看supported-versions,但请你先别急着引入该框架,继续往后看。
    MockitoPowerMock
    2.8.9+2.x
    2.8.0-2.8.91.7.x
    2.7.51.7.0RC4
    2.4.01.7.0RC2
    2.0.0-beta - 2.0.42-beta1.6.5-1.7.0RC
    1.10.8 - 1.10.x1.6.2 - 2.0
    1.9.5-rc1 - 1.9.51.5.0 - 1.5.6
    1.9.0-rc1 & 1.9.01.4.10 - 1.4.12
    1.8.51.3.9 - 1.4.9
    1.8.41.3.7 & 1.3.8
    1.8.31.3.6
    1.8.1 & 1.8.21.3.5
    1.81.3
    1.71.2.5

    我更加建议你将 Mockito升级到大于v3.0.0的版本使用,其会更加简单稳定。

    
    <dependency>
        <groupId>org.mockitogroupId>
        <artifactId>mockito-inline<artifactId>
        <version>4.11.0version>
        <scope>testscope>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    Mockito的版本大于v3.0.0

    直接展示下如何使用。

    // 放在try中其Mock会自动关闭,建议都这么做,以免影响其他单元测试
    try (MockedStatic<StaticExampleClass> staticExampleClassMock = Mockito.mockStatic(StaticExampleClass.class) ){
        staticExampleClassMock.when(StaticExampleClass::execXxx).thenReturn("");
        // 编写业务代码单元测试
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    一个比较规矩的单元测试示例

    其他一些问题

    若你的Sping版本比较低,但是使用Mockito的版本比较高,比如上面我提到的4.11.0,可能会出现这些错误信息:

    java.lang.IllegalStateException: Could not initialize plugin: interface org.mockito.plugins.MockMaker (alternate: null)
    
    Caused by: java.lang.IllegalStateException: Failed to load interface 
    
    Caused by: java.lang.reflect.InvocationTargetException
    	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    	at 
    
    Caused by: org.mockito.exceptions.base.MockitoInitializationException: 
    It seems like you are running Mockito with an incomplete or inconsistent class path. Byte Buddy could not be loaded.
    
    Byte Buddy is available on Maven Central as 'net.bytebuddy:byte-buddy' with the module name 'net.bytebuddy'.
    For the inline mock maker, 'net.bytebuddy:byte-buddy-agent' with the module name 'net.bytebuddy.agent' is also required.
    Normally, your IDE or build tool (such as Maven or Gradle) should take care of your class path completion but 
    	at org.mockito.internal.exceptions.Reporter.missingByteBuddyDependency(Reporter.java:1131)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    此时,请检查项目中实际依赖情况:

    1. 实际引入mockito-core的版本是否与mockito-inline内置依赖版本一致?
    2. 实际引入byte-buddybyte-buddy-agentobjenesis的版本是否与mockito-core内置依赖版本一致?

    若不一致,请手动显式添加上述依赖,并令其版本为mockito-coremockito-inline内置对应版本。

    值得一提的是,Mockito官方开发团队给出了上述第二个问题的发生原因:

    Unfortunately Spring hardcodes a specific (older) version of ByteBuddy, which becomes problematic for evergreen projects such as Mockito. Therefore, explicitly specify version.

    That’s all~

  • 相关阅读:
    java基于SpringBoot+Vued的小区物业管理系统 elementui 前后端分离
    JVM监控工具jstat使用介绍
    Oracle根据时间查询
    【C++】:string用法详解
    无需破解,官网安装Visual Studio 2013社区版
    以太坊的账户(外部账户和合约账户)
    python实现全向轮EKF_SLAM
    面向5G通信的射频关键技术解决毫米波传播距离短难题
    python3 win环境部署
    完美解决在Latex的表格里的单元格内的文本紧贴着上边框线条的问题
  • 原文地址:https://blog.csdn.net/qq_37939786/article/details/137959151