解决 JUnit 版本引起的 SpringBoot 测试环境加载问题

SpringBoot 项目初始化后尝试自己编写测试类时报错空指针异常,在此记录下解决方法,如有错误,欢迎指正!

1. 问题描述

1.1 报错信息

在执行 Spring Boot 单元测试时遇到如下报错信息:

java.lang.NullPointerException
	at com.thr.usercenter.SampleTest.testSelect(SampleTest.java:25)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

1.2 报错代码

  • src/test/java/com/thr/usercenter/SampleTest.java
import com.thr.usercenter.mapper.UserMapper;
import com.thr.usercenter.model.User;
import org.junit.Assert;
import org.junit.Test;
import org.springframework.boot.test.context.SpringBootTest;

import javax.annotation.Resource;
import java.util.List;

@SpringBootTest
public class SampleTest {

    @Resource
    private UserMapper userMapper;

    @Test
    public void testSelect() {
        System.out.println(("----- selectAll method test ------"));
        // 查询所有
        List<User> userList = userMapper.selectList(null);
        // 这里判断查出来的是否有五条数据
        Assert.assertEquals(5, userList.size());
        userList.forEach(System.out::println);
    }
}

2. 报错分析

报错说明在代码中的这行:

List<User> userList = userMapper.selectList(null);

出现了空指针错误,看起来是找不到 userMapper

从报错输出来看,连 Springboot 都没启动,那么问题可能与 Spring Boot 测试环境未能正确初始化有关,解决方法如下:

2.1 方法一:使用 @RunWith 注解

  • 在 JUnit 4 环境下,Spring Boot 测试类需要使用 @RunWith(SpringRunner.class) 注解来引导测试环境的加载

  • 由于测试环境未正确加载,UserMapper bean未能成功注入,因此在执行 userMapper.selectList(null) 时抛出了NullPointerException

  • 修改后完整代码如下

    添加了 @RunWith(SpringRunner.class) 注解这行

import com.thr.usercenter.mapper.UserMapper;
import com.thr.usercenter.model.User;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import javax.annotation.Resource;
import java.util.List;

@SpringBootTest
@RunWith(SpringRunner.class)
public class SampleTest {

    @Resource
    private UserMapper userMapper;

    @Test
    public void testSelect() {
        System.out.println(("----- selectAll method test ------"));
        // 查询所有
        List<User> userList = userMapper.selectList(null);
        // 这里判断查出来的是否有五条数据
        Assert.assertEquals(5, userList.size());
        userList.forEach(System.out::println);
    }
}
  • pom.xml中的 junit4 依赖:
<!-- https://mvnrepository.com/artifact/junit/junit -->
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.13.2</version>
    <scope>test</scope>
</dependency>
  • 运行成功:

2.2 方法二:使用 JUnit 5

  • 其实在 Spring Boot 2.2 以上的版本,就已经集成了 JUnit 5,不需要使用@RunWith注解,简化了测试环境的配置和bean注入过程

  • 修改为 JUnit 5 的操作

    • 只需要 spring-boot-starter-test 依赖,所以不需要修改 pom.xml
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    
    • 使用org.junit.jupiter.api.Test替换org.junit.Test
    • 使用org.junit.jupiter.api.Assertions替换org.junit.Assert
  • 修改后完整代码如下

import com.thr.usercenter.mapper.UserMapper;
import com.thr.usercenter.model.User;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import javax.annotation.Resource;
import java.util.List;

@SpringBootTest
public class SampleTest {

    @Resource
    private UserMapper userMapper;

    @Test
    public void testSelect() {
        System.out.println(("----- selectAll method test ------"));
        // 查询所有
        List<User> userList = userMapper.selectList(null);
        // 这里判断查出来的是否有五条数据
        Assertions.assertEquals(5, userList.size());
        userList.forEach(System.out::println);
    }
}

3. 总结

JUnit版本差异

  • JUnit 4 和 JUnit 5 在集成 Spring Boot 测试时的要求有所不同。JUnit 5 提供了更简洁的测试环境配置方式,与 Spring Boot 的集成更加自然,而 JUnit 4 则需要额外的配置。
posted @ 2024-01-29 16:49  路有所思  阅读(663)  评论(0)    收藏  举报