前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >mockito入门

mockito入门

作者头像
查拉图斯特拉说
发布2023-10-25 15:49:28
3030
发布2023-10-25 15:49:28
举报
文章被收录于专栏:后端架构后端架构

前言

最近在项目中跑单元测试发现直接使用springboot自带的测试,一整套跑起来花费数十分钟,这是无法忍受的,考虑到功能的特殊性,想到了Spring测试包自带的mockito单元测试,所以进行初次尝试使用。

测试代码

pom包

在这里插入图片描述
在这里插入图片描述
代码语言:javascript
复制
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-test</artifactId>
   <scope>test</scope>
</dependency>

<dependency>
   <groupId>org.mockito</groupId>
   <artifactId>mockito-inline</artifactId>
   <version>4.5.1</version>
   <scope>test</scope>
</dependency>
代码语言:javascript
复制
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;

    /**
     * @author Steven
     * @Date 2023/1/30 15:45
     */
    @Service
    public class OrderA {

        @Autowired
        private OrderC orderC;

        public int print() {
            System.out.println("D = "+ OrderD.getResult());
            System.out.println(orderC.print(2));
            System.out.println("hello world");
            return -1;
        }

    }
代码语言:javascript
复制
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;

    /**
     * @author Steven
     * @Date 2023/1/30 15:46
     */
    @Service
    public class OrderB {

        @Autowired
        private OrderA order;

        public boolean test() {
            System.out.println("order B test()");
            System.out.println("order value = " + order.print());
            System.out.println("order B hello world");
            return true;
        }

    }
代码语言:javascript
复制
    import org.springframework.stereotype.Service;

    /**
     * @author Steven
     * @Date 2023/1/30 16:43
     */
    @Service
    public class OrderC {

        public int print(int a) {
            System.out.println("hello"+ a);
            return -1;
        }
    }
代码语言:javascript
复制
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;

    /**
     * @author Steven
     * @Date 2023/1/30 17:32
     */
    @Component
    public class OrderD {
        private static OrderC orderC;

        @Autowired
        public OrderD(OrderC orderCa) {
            System.out.println("==================");
            orderC = orderCa;
        }

        public static int getResult(){
            System.out.println("hhhhh====" + OrderE.print());
            return orderC.print(3);
        }

    }
代码语言:javascript
复制
    /**
     * @author Steven
     * @Date 2023/1/31 14:04
     */
    public class OrderE {

        public static int print() {
            System.out.println("ahhahahahahhaha");
            return 1111111;
        }
        
    }

主要测试类

代码语言:javascript
复制
    import com.timelinecapital.web.service.order.*;
    import org.checkerframework.checker.units.qual.A;
    import org.junit.jupiter.api.Assertions;
    import org.junit.jupiter.api.Test;
    import org.junit.jupiter.api.extension.ExtendWith;
    import org.mockito.MockedStatic;
    import org.mockito.Mockito;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.mock.mockito.MockBean;
    import org.springframework.test.context.ContextConfiguration;
    import org.springframework.test.context.junit.jupiter.SpringExtension;

    import static org.mockito.ArgumentMatchers.anyInt;
    import static org.mockito.BDDMockito.then;
    import static org.mockito.Mockito.when;

    /**
     * @author Steven
     * @Date 2023/1/30 15:48
     */
    @ContextConfiguration(classes = {OrderB.class, OrderA.class, OrderC.class, OrderD.class})
    @ExtendWith(SpringExtension.class)
    public class OrderTest {

        @Autowired
        private OrderB orderB;

        @MockBean
        private OrderC orderC;


        @Test
        public void testOrder() throws Exception {
            Mockito.mockStatic(OrderE.class);
    //        try (MockedStatic<OrderE> orderEMockedStatic = Mockito.mockStatic(OrderE.class)) {
                when(OrderE.print()).thenReturn(333);
    //            orderEMockedStatic.close();
    //        }
    //        when(orderA.print()).thenReturn(100);
    //        when(orderC.print(anyInt())).thenReturn(101);
            when(orderC.print(anyInt())).thenReturn(201);

            boolean res = orderB.test();

            Assertions.assertTrue(res);
        }

    }

测试代码说明:

代码语言:javascript
复制
@ExtendWith(SpringExtension.class) 这个注解重要是继承spring的环境

@ContextConfiguration 这个注解主要
    - classes属性主要是导入springbean,如果不配置需要倒入的bean会报依赖注入异常

默认情况需要手动配置相关需要注入bean的类否则会报错,依赖注入异常,找不到相应的bean

代码语言:javascript
复制
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'orderB': Unsatisfied dependency expressed through field 'order'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.timelinecapital.web.service.order.OrderA' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:659)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:639)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:119)

有些时间需要mock静态方法,单纯的使用Mockito.mockStatic(OrderE.class);会报错,需要导入mockito-inline包,具体原因后续分析 常见的错误异常有,这错误异常很友好都提示了如何操作:

代码语言:javascript
复制
org.mockito.exceptions.base.MockitoException: 
The used MockMaker SubclassByteBuddyMockMaker does not support the creation of static mocks

Mockito's inline mock maker supports static mocks based on the Instrumentation API.
You can simply enable this mock mode, by placing the 'mockito-inline' artifact where you are currently using 'mockito-core'.
Note that Mockito's inline mock maker is not supported on Android.

总结

默认情况下需要手动配置相对应的所有需要注入的bean,凡是你这个模块需要倒入的bean你都需要配置,如果你不配置注入就会报错,要么注入,要么mock,比如OrderB里面依赖了OrderA和一个静态的OrderD类,OrderA bean要么mock要么注入,OrderD就不一样了因为是静态的,但是导入的时候需要注入OrderC所以站在Spring的角度,都需要注入。当然也可以一开始就mock,当一个实例被mock之后他就成虚拟的了,他的依赖就不需要进行注入了。 站在项目的角度,项目越大不可能为了某个功能跑一次服务,因为服务还有其他功能,所以功能测试就成了很好的解决方案,你可以随意的mock,返回想要的值,最大角度的覆盖所有测试,唯一的缺点是,你需要考虑所有的依赖注入。

引用

使用Mockito模拟Static静态方法 https://blog.csdn.net/qq_38646452/article/details/124943944

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-10-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 测试代码
  • 总结
  • 引用
相关产品与服务
腾讯云服务器利旧
云服务器(Cloud Virtual Machine,CVM)提供安全可靠的弹性计算服务。 您可以实时扩展或缩减计算资源,适应变化的业务需求,并只需按实际使用的资源计费。使用 CVM 可以极大降低您的软硬件采购成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档