Mockito框架里面的@Mock注解原理

简介: 一文看懂@Mock注解的底层的底层原理:@Mock注解的底层其实就是用cglib

@Mock注解就是其实就是用cglib的原理帮我们new了一个@Mock注解作用类的子类,什么意思呢,往下看

20190711141228183

首先是Company,此时hh方法返回值是”字符串”,

package com.one.util;

import lombok.AllArgsConstructor;
import lombok.Data;

@Data
@AllArgsConstructor
public class Company {
    private String name;

    public String hh(){
        return "字符串";
    }
}

User类,mm()的返回值就是Company类的hh()返回值

package com.one.util;

import lombok.AllArgsConstructor;
import lombok.Data;

@Data
@AllArgsConstructor
public class User {
    private  Company company;

    private int age;


    public String mm(){
       return company.hh();
    }
}

然后UserTest类如下,此时可以看到下面的Company上面放了@Mock注解,他的作用就是帮我们生产一个Company类的子类(假如是CompanyZi),然后使用多态赋值给下面的company(就像这样Company company=new CompanyZi),而且这个ComanyZi类里面的hh()方法的返回值是null,为什么这样说呢,我们看下面的结果

package com.one.util;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;

import static org.assertj.core.api.Assertions.catchThrowable;

@RunWith(MockitoJUnitRunner.class)
public class UserTest {

    @Mock
    private Company company;

    private User user;

    @Before
    public void setUp() {
        user = new User(company, 1);
    }

    @Test
    public void tt() {
        catchThrowable(() -> {
            String mm = user.mm();
            System.out.println(mm);
        });
    }

}

此时可以看到结果是null

20190711141344750

简单来说上面的代码可以变成下面这样

20190711141410267

首先是Company,此时hh方法返回值是”字符串”,

package com.one.util;

import lombok.AllArgsConstructor;
import lombok.Data;

@Data
@AllArgsConstructor
public class Company {
    private String name;

    public String hh(){
        return "字符串";
    }
}

User类,mm()的返回值就是Company类的hh()返回值

package com.one.util;

import lombok.AllArgsConstructor;
import lombok.Data;

@Data
@AllArgsConstructor
public class User {
    private  Company company;

    private int age;


    public String mm(){
       return company.hh();
    }
}

然后UserTest类如下,此时下面的类ComapanyZi就相当于上面的被@Mock注解的company的最终被new的对象,只不过@Mock注解帮我做了下面的CompanyZi这个类,此时可以看到下面的ComapanyZi返回的是null

package com.one.util;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

import static org.assertj.core.api.Assertions.catchThrowable;

@RunWith(JUnit4.class)
public class UserTest {

    class ComapanyZi extends Company{
        public ComapanyZi(String name) {
            super(name);
        }
        public String hh(){
            return null;
        }
    }
    private User user;

    @Test
    public void name() {
        user=new User(new ComapanyZi("zi"),1);
        Throwable throwable = catchThrowable(() -> {
            System.out.println(user.mm());
        });
    }
}

此时可以看到结果是null

20190711141524966

我们可以验证上面的结论

就是给@Mock注解的类添加一个final,然后在运行的时候就报错了

20190711141543906

Company类,此时可以看到Compan已经被final修改了

package com.one.util;

import lombok.AllArgsConstructor;
import lombok.Data;

@Data
@AllArgsConstructor
public final class Company {
    private String name;

    public String hh(){
        return "字符串";
    }
}

User类

package com.one.util;

import lombok.AllArgsConstructor;
import lombok.Data;

@Data
@AllArgsConstructor
public class User {
    private  Company company;

    private int age;


    public String mm(){
       return company.hh();
    }
}

然后测试如下,然后运行下面的name方法,然后结果如下所示

package com.one.util;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;


@RunWith(MockitoJUnitRunner.class)
public class UserTest {

    @Mock
    private Company company;

    private User user;

    @Before
    public void setUp(){
        user = new User(company,1);
    }

    @Test
    public void name() {
        user.mm();
    }
}

此时可以看到报错了,说Company不能被final修改,者更好符号cglib的规则

20190711141632887

原文链接

目录
相关文章
安装Xftp7时出现致命错误:-1603的解决方法
安装Xftp7时出现致命错误:-1603的解决方法
1991 0
安装Xftp7时出现致命错误:-1603的解决方法
|
12月前
|
小程序 Java 关系型数据库
基于微信小程序的博物馆文创系统
本研究聚焦基于微信小程序的博物馆文创系统,结合Java、SpringBoot与MySQL技术,构建集文创销售、互动体验与文化传播于一体的数字化平台,提升用户体验与文化服务效能。
|
存储 监控 物联网
RFID仓储管理几大核心要素
RFID仓储管理系统通过多个核心要素实现智能化管理。其中包括RFID标签选型,根据物品特性选择适合的标签类型;RFID读写器选型,合理布局以覆盖关键区域;中间件处理数据,提升系统兼容性;仓储管理系统(WMS)实时监控库存与作业调度;人员培训确保规范操作。该系统在入库、出库、盘点等环节减少人工失误,降低成 本,提高效率,推动仓储管理向自动化、数字化转型。
|
存储 安全 数据可视化
如何开发人事管理系统中的薪酬管理板块?(附架构图+流程图+代码参考)
本文深入解析了企业薪酬管理模块的开发与实现,涵盖模块概述、核心功能、业务流程及开发技巧。通过实际代码示例,帮助开发人员构建高效、灵活的薪酬管理系统,提升企业人事管理效率与数据准确性。
|
IDE Java API
IDEA 2022 之 Lombok 使用 教程
IDEA 2022 之 Lombok 使用 教程
1916 0
|
关系型数据库 Serverless 分布式数据库
PolarDB PostgreSQL版Serverless技术原理解读
数据库是现代企业IT系统中非常重要的一部分。在创建数据库时,客户往往需要比较保守地去配置数据库集群的资源,包括CPU、内存、存储以及连接数等多种参数配置,以确保业务能够在波峰和波谷都能平稳运行。在这种情况下,客户购买的集群资源在业务波谷时期会被闲置,导致整体成本偏高;而在业务压力增长阶段,集群资源又应对不足。Serverless数据库可以很好地解决这个问题。它能够让数据库集群资源随客户业务负载动态弹性扩缩,将客户从复杂的业务资源评估和运维工作中解放出来。 本文描述PolarDB PostgreSQL版Serverless的构建中, 如何实现弹得快、弹得准、弹得稳、弹得广的几个关键技术点。
77325 18
PolarDB PostgreSQL版Serverless技术原理解读
|
JavaScript 关系型数据库 Java
IDEA插件-EasyCode
EasyCode是基于IntelliJ IDEA Ultimate版开发的一个代码生成插件,主要通过自定义模板(基于velocity)来生成各种你想要的代码。通常用于生成Entity、Dao、Service、Controller。如果你动手能力强还可以用于生成HTML、JS、PHP等代码。理论上来说只要是与数据有关的代码都是可以生成的。
1815 0
IDEA插件-EasyCode
|
存储 Linux PHP
PHP云盘网盘系统源码+快速对接多家云存储+全新一键安装版
快速对接多家云存储,支持七牛、又拍云、阿里云OSS、AWS S3、Onedrive、自建远程服务器,当然,还有本地存储。 自定义主题配色。 图片、音频、视频、文本、Markdown、Ofiice文档 在线预览。 移动端全站响应式布局。 文件、目录分享系统,可创建私有分享或公开分享链接。 用户个人主页,可查看用户所有分享。 多用户系统、用户组支持。 初步完善的后台,方便管理。 拖拽上传、分片上传、断点续传、下载限速(*实验性功能)。 多上传策略,可为不同用户组分配不同策略。 用户组基础权限设置、二步验证。 WebDAV协议支持。
918 2