【记录】用JUnit 4的@Test注解时报错java.lang.NullPointerException的原因与解决方法

项目场景:

在练习黑马点评的逻辑过期解决缓存击穿时,编写了一个预热缓存数据的单元测试

@SpringBootTest
public class HmDianPingApplicationTests {@Resourceprivate ShopServiceImpl shopService;@Testpublic void testSaveShop() throws InterruptedException {shopService.saveShop2Redis(1L,10L);}}

运行时报空指针异常

java.lang.NullPointerException: Cannot invoke "com.hmdp.service.impl.ShopServiceImpl.saveShop2Redis(java.lang.Long, java.lang.Long)" because "this.shopService" is null

原因分析:

这是由于选择的@Test注解选错了,应该选择org.junit.jupiter.api的那一个而不是org.junit的那一个。前者对应JUnit 5单元测试框架 后者对应JUnit 4单元测试框架。两者的对比如下:

JUnit 4: org.junit.Test

  • 用途: JUnit 4 提供的基础单元测试注解,用于标记测试方法。

  • 特点: 不支持重复测试、参数化测试等高级功能(需要额外扩展)。

  • 测试方法必须是 public 的。(这也是为什么如果用了这个注解,测试方法没加public的话就没有启动运行的绿色箭头的原因)

  • 必须配合 JUnit 4 的测试运行器使用(如 @RunWith)。

JUnit 5: org.junit.jupiter.api.Test

  • 用途: JUnit 5(JUnit Jupiter)提供的现代化测试注解,是 JUnit 的全新版本。

  • 特点: 无需方法是public(包级权限或 protected 也可)。

  • 支持更多功能,如重复测试(@RepeatedTest)、参数化测试(@ParameterizedTest)。
    更强的扩展性,支持条件测试(如 @EnabledIf)。

  • 无需 @RunWith,改用 @ExtendWith 或直接支持 Spring的测试环境。

JUnit 4 中,Spring 和测试的整合依赖于 @RunWith(SpringRunner.class)(或较早的 SpringJUnit4ClassRunner)。
如果没有添加 @RunWith(SpringRunner.class) 注解,Spring 的测试上下文不会加载,@SpringBootTest 的功能无法生效。
结果是,@Resource(或 @Autowired)的依赖注入不会生效,导致 shopService 为 null。

JUnit 5 使用 SpringExtension(通过 @ExtendWith(SpringExtension.class) 内部实现)来加载 Spring 测试上下文。
@SpringBootTest 会自动应用 SpringExtension,所以无需显式声明 @ExtendWith,Spring 上下文会被正确加载。

因此,在 JUnit 4 中,如果你遗漏了 @RunWith(SpringRunner.class),Spring 的功能不会生效,而在 JUnit 5 中,这一步是自动完成的。

所以为什么 shopService 是 null呢?

shopService 的注入依赖于 Spring 容器。如果 Spring 测试上下文没有正确加载:
@Resource 或 @Autowired 不会生效。
导致 shopService 没有被注入,值为 null。
调用 shopService.saveShop2Redis(...) 时自然会抛出 NullPointerException。
在 JUnit 4 中,如果没有正确使用 @RunWith(SpringRunner.class):
Spring 测试上下文未加载,shopService 不会被注入。
这也是为什么用 JUnit 4 会抛出 NullPointerException,而 JUnit 5 不会的根本原因。

解决方案:

方法一 :修复JUnit 4的问题 ,在使用时添加@RunWith(SpringRunner.class)

@RunWith(SpringRunner.class) // 启用 Spring 的测试功能
@SpringBootTest
public class HmDianPingApplicationTests {@Resourceprivate ShopServiceImpl shopService;@Testpublic void testSaveShop() {shopService.saveShop2Redis(1L, 10L);}
}

方法二:优先选用JUnit 5的Test注解

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/62459.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

echarts使用整理

4、条形分区统计 <div ref"chartsVal1" class"chartsline-div"></div> const chartsVal1 ref(null); const chartsVal1Title ref(运行时间统计);drewCharts2(chartsVal1, chartsVal1Title.value);function drewCharts2(id, title) {const m…

【八股】HTTP

浏览器输入URL之后发生的过程 浏览器解析URL中的协议&#xff0c;主机&#xff0c;端口&#xff0c;路径参数等DNS域名解析得到对应的IP地址通过IP和PORT对服务器发送TCP三次握手建立连接浏览器发送请求服务器接受请求&#xff0c;处理并响应浏览器得到HTTP响应&#xff0c;对…

torch.optim.lr_scheduler.ReduceLROnPlateau

torch.optim.lr_scheduler.ReduceLROnPlateau 是 PyTorch 中的一种学习率调度器&#xff0c;主要用于在模型训练过程中根据某些指标&#xff08;如验证损失&#xff09;动态调整学习率。它是一种基于性能指标动态调整学习率的策略&#xff0c;而不是预定义的固定时间调整。 主要…

ubuntu下的chattts 学习6:音色固定的学习

魔搭社区 该区提供了随机种子级音乐的试听与下载。 spk torch.load(<PT-FILE-PATH>) params_infer_code {spk_emb: spk, } 略 测试过程&#xff1a; 1.先建一个文件夹&#xff1a;然后从上面的网站上下载了两个。放在里面测试 2 2.测试代码 import ChatTTS impo…

数据集的重要性:如何构建AIGC训练集

文章目录 一、为什么数据集对AIGC如此重要&#xff1f;1. 数据决定模型的知识边界2. 数据质量直接影响生成效果3. 数据集多样性提升模型鲁棒性 二、构建AIGC训练集的关键步骤1. 明确目标任务和生成需求2. 数据源的选择3. 数据清洗与预处理4. 数据标注5. 数据增强 三、针对不同类…

47 基于单片机的书库环境监测

目录 一、主要功能 二、硬件资源 三、程序编程 四、实现现象 一、主要功能 基于51单片机&#xff0c;采用DHT11湿度传感器检测湿度&#xff0c;DS18B20温度传感器检测温度&#xff0c; 采用滑动变阻器连接数模转换器模拟二氧化碳和氧气浓度检测&#xff0c;各项数值通过lc…

【操作系统】每日 3 题(五十五)

✍个人博客&#xff1a;https://blog.csdn.net/Newin2020?typeblog &#x1f4e3;专栏地址&#xff1a;https://blog.csdn.net/newin2020/category_12820365.html &#x1f4da;专栏简介&#xff1a;在这个专栏中&#xff0c;我将会分享操作系统面试中常见的面试题给大家~ ❤️…

服务器加固

1.服务器密码复杂度 密码最小长度&#xff0c;密码复杂度策略 vim /etc/pam.d/system-auth --------------- #密码配置 #ucredit&#xff1a;大写字母个数&#xff1b;lcredit&#xff1a;小写字母个数&#xff1b;dcredit&#xff1a;数字个数&#xff1b;ocredit&#xff1a;…

spring boot 同一个redis 操作不同的库

1.下面是在Spring Boot中配置多个Redis数据库的几种方式&#xff1a; 1.1 配置如下# application.yml spring:redis:host: localhostport: 6379password: your_password# 连接池配置lettuce:pool:max-active: 8max-idle: 8min-idle: 0max-wait: -1mstimeout: 5000ms# 多个数据…

C语言面试题/笔试题/高频面试题_2

9. 全局变量和局部变量的区别 定义&#xff1a;全局变量是定义在函数外部的变量&#xff0c;局部变量是定义在 函数内部的变量 存储位置&#xff1a;全局变量存储在全局区&#xff0c;局部变量存储在栈区 作用域&#xff1a;全局变量可以在程序任意位置使用&#xff0c;局部变量…

Brain.js(八):RNNTimeStep 实战教程 - 股票价格预测 - 实操需警慎

前置声明&#xff0c;个人浅度炒股&#xff0c;但计划将基金转入股市。然后 股市有风险&#xff0c;不是技术可以完全预测的&#xff0c;但是在无头绪的时候&#xff0c;用技术指标做个参考也不错。 本文涉及到的股票预测&#xff0c;只是代码简单示例&#xff0c;实操需警慎&a…

MySQL | 尚硅谷 | 第13章_约束

MySQL笔记&#xff1a;第13章_约束 文章目录 MySQL笔记&#xff1a;第13章_约束第13章_约束 1. 约束(constraint)概述1.1 为什么需要约束1.2 什么是约束1.3 约束的分类演示代码 2. 非空约束2.1 作用2.2 关键字2.3 特点2.4 添加非空约束2.5 删除非空约束演示代码 3. 唯一性约束3…

《计算机网络》(408大题)

2009 路由转发和静态路由的计算 子网划分、路由聚合的计算 注&#xff1a;CIDR中的子网号可以全为0或1&#xff0c;但是其主机号不允许。 注&#xff1a; 这里其实是把到互联网的路由当做了一个默认路由&#xff08;当一个目的网络地址与路由表中其他都不匹配时&#xff0c;…

NanoLog起步笔记-6-StaticLogInfo

nonolog起步笔记-6-StaticLogInfo StaticLogInfo文件名和行号文件名和行号的传入log参数 RuntimeLogger::registerInvocationSitelogid为什么只能被赋一次值 reserveAlloc加入消息头finishAlloc返回 StaticLogInfo 写C语言编译前端时&#xff0c;给我印象深刻的一部分是&#…

软件工程 概述

软件 不仅仅是一个程序代码。程序是一个可执行的代码&#xff0c;它提供了一些计算的目的。 软件被认为是集合可执行的程序代码&#xff0c;相关库和文档的软件。当满足一个特定的要求&#xff0c;就被称为软件产品。 工程 是所有有关开发的产品&#xff0c;使用良好定义的&…

Sui 集成 Phantom,生态迎来全新里程碑

作为领先的非托管多链加密&#x1f45b;&#xff0c;Phantom 宣布将支持 Sui 区块链。Sui 将加入 Solana、Bitcoin 和 Ethereum 队伍&#xff0c;成为该 wallet 支持的少数 L1 区块链之一。 此次集成也大幅提升了 Phantom 的互操作性&#xff0c;同时表明 wallet 提供商和应用…

目标跟踪领域经典论文解析

亲爱的小伙伴们&#x1f618;&#xff0c;在求知的漫漫旅途中&#xff0c;若你对深度学习的奥秘、JAVA 、PYTHON与SAP 的奇妙世界&#xff0c;亦或是读研论文的撰写攻略有所探寻&#x1f9d0;&#xff0c;那不妨给我一个小小的关注吧&#x1f970;。我会精心筹备&#xff0c;在…

如何解决 java.nio.charset.CoderMalfunctionError: 编码器故障错误问题?亲测有效的解决方法!

java.nio.charset.CoderMalfunctionError 是一个在 Java 中相对较少遇到的异常&#xff0c;通常与字符编码转换过程中的错误有关。当 Java 程序在进行字符编码转换时&#xff0c;遇到无法处理的字符或编码故障时&#xff0c;就会抛出该异常。 1. 问题描述 java.nio.charset.C…

低级爬虫实现-记录HCIP云架构考试

因工作需要考HCIP云架构&#xff08;HCIP-Cloud Service Solution Architect&#xff09;证书, 特意在淘宝上买了题库&#xff0c; 考过了。 事后得知自己被坑了&#xff0c; 多花了几十大洋。 所以想着在授权期内将题库“爬”下来&#xff0c; 共享给大家。 因为整个过程蛮有…

QGroundControl之5-AppSettings.cc

介绍 应用程序设置 Application Settings &#xff0c;这里看下语言选择功能&#xff0c;它是怎么和json文件关联起来的&#xff0c;刚刚看的时候&#xff0c;很是奇怪这么多的json文件作用。 1.AppSettings.cc 文件怎么和App.SettingsGroup.json关联 在AppSettings.cc文件没…