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

原文链接

目录
相关文章
|
存储 安全 网络协议
阿里云SSL数字证书原理、使用、申请流程及部署方式
本文带您了解阿里云数字证书的基本原理、使用、申请流程及部署方式
|
存储 监控 物联网
RFID仓储管理几大核心要素
RFID仓储管理系统通过多个核心要素实现智能化管理。其中包括RFID标签选型,根据物品特性选择适合的标签类型;RFID读写器选型,合理布局以覆盖关键区域;中间件处理数据,提升系统兼容性;仓储管理系统(WMS)实时监控库存与作业调度;人员培训确保规范操作。该系统在入库、出库、盘点等环节减少人工失误,降低成 本,提高效率,推动仓储管理向自动化、数字化转型。
|
IDE Java API
IDEA 2022 之 Lombok 使用 教程
IDEA 2022 之 Lombok 使用 教程
1777 0
|
敏捷开发 JavaScript 测试技术
深入理解与应用软件测试中的Mock技术
【5月更文挑战第5天】 在现代软件开发过程中,单元测试作为保障代码质量的重要环节,其独立性和可靠性至关重要。Mock技术应运而生,为开发者提供了一种在隔离环境下模拟外部依赖的方法。本文将深入探讨Mock技术的概念、实现方式及其在软件测试中的应用,旨在帮助读者更好地理解和运用这一强大的测试工具,以提升测试效率和软件质量。
|
Web App开发 iOS开发
Motrix开源下载管理器
Motrix开源下载管理器
658 0
|
机器学习/深度学习 算法 计算机视觉
openpose的一些个人理解
一直都是在做一些目标检测的研究工作,近期开始看一些有关姿态检测的内容,其中最经典的就是openpose这个框架,后面很多动作识别、姿态检测也大多是在该网络上进行改进,比如Real-time 2D Multi-Person Pose Estimation on CPU 这篇论文,在原OpenPose基础上进行了轻量处理,我也用这代码跑了一下,效果也不错。
978 0
openpose的一些个人理解
|
JSON 数据格式
非常实用的5种json数组去重方法,函数实现思路竟是chatgpt帮我写的!
你敢信这5种json数组去重方法的实现思路竟然是chatgpt写的,chatgpt对函数的理解也太准确了吧!
1220 0
|
算法 异构计算
m基于FPGA的256QAM调制信号产生模块verilog实现,包含testbench
m基于FPGA的256QAM调制信号产生模块verilog实现,包含testbench
709 0