Mockito框架抛出NullPointerException

简介: 一文详细讲解Mockito框架是怎么抛出NullPointerException的整个过程和解决方式。

首先看一下Mockito框架是怎么抛出NullPointerException

比如下面的代码

20190716183657401

Company类

package com.one.util;

import java.util.List;

import lombok.AllArgsConstructor;
import lombok.Data;

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

    public String companyList(List<Company> companies){
        return companies.get(0).getName();
    }
}

Person类如下

package com.one.util;

import java.util.ArrayList;
import java.util.List;

import lombok.Data;

@Data
public class Person {

    private Company company;

    public  Person(Company company) {
        this.company = company;
    }

    public String test1() {
        List companyList = new ArrayList<Company>();
        companyList.add(company);
        return this.test2(company.companyList(companyList));
    }

    public String test2(String name) {
        return name.toString();
    }
}

PersonTest 测试类代码如下

package com.one.util;


import java.util.ArrayList;
import java.util.List;

import org.assertj.core.api.Assertions;
import org.assertj.core.util.Lists;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.runners.MockitoJUnitRunner;


@RunWith(MockitoJUnitRunner.class)
public class PersonTest {
    @Mock
    private Company company;

    private Person person;

    @Before
    public void setUp(){
        person = new Person(company);
    }

    @Test
    public void show() {
        List<Company> companies = Lists.newArrayList();
        Mockito.when(company.companyList(companies)).thenReturn("hello");
        String s = person.test1();
        Assertions.assertThat(s).isEqualTo("hello");
    }
}

然后执行上面的测试方法show(),此时结果就会抛出空指针异常了,这是什么原因呢,我么往下看

20190716183937659

分析上面为什么抛出NullPointerException

这是因为你的测试方法show()方法里面的Mockito.when(company.companyList(companies)).thenReturn("hello")里面的变量companies变量的地址和真正执行到Company类里面的companyList方法里面的companies参数变量的地址是不一样的,所以真正执行的时候,调用Mockito.when(company.companyList(companies)).thenReturn("hello")返回的就是null

就比如下面的companies的变量是OX001

20190716185955350

然后当真正执行到Company类里面的companyList()方法的时候,因为test1()方法里面有重新new了一个集合当成companyList()方法的参数,此时test1()方法里面又重新new的集合companyList变量的地址就会是OX003,

20190716185858116
然后因为show()测试方法里面companies变量的地址和test1()方法里面的new的companyList变量的地址是不同的,所以show()方法里面的Mockito.when(company.companyList(companies)).thenReturn("hello")是执行不成功的,然后就会返回null,然后因为在test1()方法里面调用test2()方法,所以此时就会抛出空指针

怎么解决这个问题呢

使用Mockito.any()就可以了
比如下面的代码

20190716183657401

Company类

package com.one.util;

import java.util.List;

import lombok.AllArgsConstructor;
import lombok.Data;

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

    public String companyList(List<Company> companies){
        return companies.get(0).getName();
    }
}

Person类如下

package com.one.util;

import java.util.ArrayList;
import java.util.List;

import lombok.Data;

@Data
public class Person {

    private Company company;

    public  Person(Company company) {
        this.company = company;
    }

    public String test1() {
        List companyList = new ArrayList<Company>();
        companyList.add(company);
        return this.test2(company.companyList(companyList));
    }

    public String test2(String name) {
        return name.toString();
    }
}

PersonTest 测试类代码如下,此时Mockito.when(company.companyList(any())).thenReturn("hello")里面使用的就是any()

package com.one.util;


import java.util.ArrayList;
import java.util.List;

import org.assertj.core.api.Assertions;
import org.assertj.core.util.Lists;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.runners.MockitoJUnitRunner;

import static org.mockito.Matchers.any;

@RunWith(MockitoJUnitRunner.class)
public class PersonTest {
    @Mock
    private Company company;

    private Person person;

    @Before
    public void setUp(){
        person = new Person(company);
    }

    @Test
    public void show() {
        List<Company> companies = Lists.newArrayList();
        Mockito.when(company.companyList(any())).thenReturn("hello");
        String s = person.test1();
        Assertions.assertThat(s).isEqualTo("hello");
    }
}

此时结果如下所示,成功了

20190716185255749

原文链接

能看到这里的同学,就帮忙右上角点个赞吧,Thanks(・ω・)ノ

目录
相关文章
|
Java API Maven
Java工具篇之反射框架Reflections
Reflections通过扫描classpath,索引元数据,并且允许在运行时查询这些元数据。 使用Reflections可以很轻松的获取以下元数据信息: - [x] 获取某个类型的全部子类 - [x] 只要类型、构造器、方法,字段上带有特定注解,便能获取带有这个注解的全部信息(类型、构造器、方法,字段) - [x] 获取所有能匹配某个正则表达式的资源 - [x] 获取所有带有特定签名的方法,包括参数,参数注解,返回类型 - [x] 获取所有方法的名字 - [x] 获取代码里所有字段、方法名、构造器的使用权
2241 0
|
SQL XML Java
菜鸟之路Day35一一Mybatis之XML映射与动态SQL
本文介绍了MyBatis框架中XML映射与动态SQL的使用方法,作者通过实例详细解析了XML映射文件的配置规范,包括namespace、id和resultType的设置。文章还对比了注解与XML映射的优缺点,强调复杂SQL更适合XML方式。在动态SQL部分,重点讲解了`&lt;if&gt;`、`&lt;where&gt;`、`&lt;set&gt;`、`&lt;foreach&gt;`等标签的应用场景,如条件查询、动态更新和批量删除,并通过代码示例展示了其灵活性与实用性。最后,通过`&lt;sql&gt;`和`&lt;include&gt;`实现代码复用,优化维护效率。
1489 5
|
人工智能 Java 测试技术
mockito入门
本内容主要介绍Mockito框架的使用,包括快速上手指南、案例分析和高级用法。涵盖Mockito资源链接、依赖配置及版本要求(4.x支持JDK1.8,5.x需JDK11+)。通过具体代码示例,讲解了Spy与Mock对象的区别及应用场景,如创建真实或虚拟对象、模拟方法调用等。同时深入探讨了做桩技术,包括对具体参数和任意参数的处理,并提供注解方式简化测试代码。此外,针对私有方法的Mock需求,介绍了PowerMockito扩展框架及反射技术的实现方式,强调了设计优化的重要性,建议通过重构避免直接Mock私有方法,以提升测试健壮性和代码可维护性。最后附有参考资料供进一步学习。
1474 8
|
测试技术
Squaretest自动生成单元测试
Squaretest自动生成单元测试
1182 8
Squaretest自动生成单元测试
|
Java 测试技术 API
在 Spring 中 Mock RestTemplate
本文介绍了两种在单元测试中 mock RestTemplate 调用的方法,避免真实 HTTP API 调用以提高测试可控性。一是使用 Mockito 模拟库,通过 @Mock 和 when/then 方法定义模拟行为;二是借助 Spring Test 提供的 MockRestServiceServer,创建模拟服务器定义请求响应交互。文中结合具体代码示例展示了两种方法的实现细节,并强调了 RestTemplate 实例的一致性配置。适用于需要模拟外部 HTTP 调用的集成测试场景。
425 1
|
缓存 移动开发 JSON
【网络安全 | 网络协议应用层】结合Wireshark讲解HTTP协议
【网络安全 | 网络协议应用层】结合Wireshark讲解HTTP协议
1810 0
|
存储 缓存 Java
程序员必懂!上下文切换到底是怎么回事?
大家好,我是小米,一个喜欢分享技术的程序员。今天聊聊社招面试中的高频考点——上下文切换。它指CPU在多个任务间切换时保存和恢复状态的过程,常见于进程、线程切换及中断处理。上下文切换有CPU时间开销、缓存失效、内存开销等代价。优化方法包括减少线程数量、选择合适的并发模型、优化锁使用等。理解这些不仅能提升面试表现,还能写出更高效的代码。欢迎关注我的微信公众号“软件求生”,获取更多技术干货!
698 6
|
存储 监控 算法
《Ceph源码分析》——导读
本节书摘来自华章出版社《Ceph源码分析》一书中的导读,作者常涛,更多章节内容可以访问云栖社区“华章计算机”公众号查看 目  录序言第1章 Ceph整体架构 **1.1 Ceph的发展历程1.2 Ceph的设计目标1.
7684 1
|
缓存 负载均衡 网络协议
|
人工智能 Java 测试技术
JDK11下Mock框架进化:从PowerMockito到Mockito Only
本文探讨了从使用PowerMock的测试环境迁移到仅使用Mockito(Mockito Only)策略的必要性和实践方法。
1017 10