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 测试技术 Android开发
Junit - 期望异常测试(Expected Test)
Junit - 期望异常测试(Expected Test)
1493 0
|
测试技术
IDEA创建单元测试与测试覆盖率统计
IDEA(IntelliJ IDEA)不仅支持快速基于当前类创建单元测试,还支持代码测试覆盖率的统计,以及生成报告和标记测试运行命中的代码。
3453 0
IDEA创建单元测试与测试覆盖率统计
|
Java 测试技术 容器
SpringBoot单元测试报空指针异常解决方案
java.lang.NullPointerException空指针异常 1.测试类中产生空指针异常,可能不是你的逻辑代码写错了,而是因为获取容器失败,即没有使用正确的测试方法 2.在SpringBoot项目中我们一般可以使用两种Junit进行测试,在导入@Test包时,会出现两个选项
1605 0
SpringBoot单元测试报空指针异常解决方案
|
XML Java Maven
MockedStatic 用于模拟静态方法
`MockedStatic` 是 Mockito 3.4.0 版本引入的一个功能,用于模拟静态方法。在之前的 Mockito 版本中,模拟静态方法是一项困难的任务,通常需要借助其他工具如 PowerMockito。但是,从 Mockito 3.4.0 开始,你可以使用 `MockedStatic` 类轻松地模拟静态方法。 以下是如何使用 `MockedStatic` 模拟静态方法的示例: 1. 首先,确保你已经添加了 Mockito 的依赖项。对于 Maven 项目,添加以下依赖项: ```xml <dependency> <groupId>org.mockito</groupId
2678 9
|
XML 设计模式 Java
PowerMock:静态方法与私有方法测试
PowerMock是Java单元测试中扩展Mockito的框架,允许模拟静态方法、构造函数、私有方法和final类,以增强测试隔离和覆盖率。主要应用场景包括静态方法模拟、私有方法测试和构造函数/Final类模拟。然而,使用时需注意配置复杂性、避免过度使用、精确控制模拟行为和遵循最佳实践。示例展示了如何模拟静态方法,通过添加PowerMock依赖和使用PowerMockito.mockStatic进行静态方法的模拟和验证。正确使用PowerMock能提升测试质量,但应谨慎以保持代码可读性和测试有效性。
649 5
PowerMock:静态方法与私有方法测试
|
10月前
|
Java 测试技术 Maven
Java一分钟之-PowerMock:静态方法与私有方法测试
通过本文的详细介绍,您可以使用PowerMock轻松地测试Java代码中的静态方法和私有方法。PowerMock通过扩展Mockito,提供了强大的功能,帮助开发者在复杂的测试场景中保持高效和准确的单元测试。希望本文对您的Java单元测试有所帮助。
1613 2
|
测试技术
详解单元测试问题之@InjectMocks注入mock对象如何解决
详解单元测试问题之@InjectMocks注入mock对象如何解决
922 1
|
Java 测试技术 Maven
单元测试问题之在Maven项目中引入JUnit 5和Mockito的依赖如何解决
单元测试问题之在Maven项目中引入JUnit 5和Mockito的依赖如何解决
783 1
|
测试技术 开发者
单元测试问题之在Mockito中静态方法的调用,如何模拟
单元测试问题之在Mockito中静态方法的调用,如何模拟