当前位置: 首页 > news >正文

【记录】用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注解

相关文章:

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

项目场景: 在练习黑马点评的逻辑过期解决缓存击穿时,编写了一个预热缓存数据的单元测试 SpringBootTest public class HmDianPingApplicationTests {Resourceprivate ShopServiceImpl shopService;Testpublic void testSaveShop() throws InterruptedE…...

Spring Boot 自动化脚本-多线程批量压缩图片

Spring Boot 自动化脚本-多线程批量压缩图片 支持多线程支持多路径配置支持断点续压支持压缩后文件层级路径不变脚本一键启动,支持本地 main 调用或远程 POST 接口调用 背景:在进行数据迁移时,发现附件文件夹过于庞大,且大都为图…...

依托 Spring Boot框架,精铸高扩展性招聘信息管控系统

1 绪 论 1.1 课题背景与意义 在Internet高速发展的今天,计算机的应用几乎完全覆盖我们生活的各个领域,互联网在经济,生活等方面有着举足轻重的地位,成为人们资源共享,信息快速传递的重要渠道。在中国,网上管…...

【前端】理解 JavaScript 对象属性访问的复杂性

博客主页: [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: 前端 文章目录 💯前言💯理论基础:JavaScript 对象属性的访问模式1. 点符号访问(Dot Notation)2. 方括号访问(Bracket Notation)点符号…...

Django异步视图adrf解决办法

提问 在Django编写异步视图的时候会出现 AssertionError: Expected a Response, HttpResponse or HttpStreamingResponse to be returned from the view 或者 TypeError: sync_to_async can only be applied to sync functions. 诸如此类的错误的时候一般发生在异步视图中…...

【一文了解】C#基础-接口

目录 1. 定义 2. 接口的特点与规则 3. 接口的实现 3.1单接口实现 3.2多接口实现 4. 接口的作用和用途 1)扩展行为 2)规范行为 3)降低耦合 5. 接口与继承的比较 1)继承 2)接口 6. 接口与抽象类的比较 1)IComparable(比较器,常用) 2)IComparer(比较器)…...

活着就好20241210

亲爱的朋友们,大家早上好!🌞 今天是10号,星期二,2024年12月的第十天,同时也是第50周的开始,农历甲辰[龙]年十一月初六日。在这晨光熹微的美好时刻,愿那温暖而明媚的阳光轻轻拂过你的…...

多表设计 - 一对一多对多

一.一对一关系概述: 例如:一位用户只能有一张身份证,一张身份证也只能对应一位用户 如果用户基本信息查询频率比用户身份信息查询频率高,为了提高效率,可拆分为两张表: 此时如何体现一对一的关系呢&#xf…...

实现 DataGridView 下拉列表功能(C# WinForms)

本文介绍如何在 WinForms 中使用 DataGridViewComboBoxColumn 实现下拉列表功能,并通过事件响应来处理用户的选择。以下是实现步骤和示例代码。 1. 效果展示 该程序的主要功能是展示如何在 DataGridView 中插入下拉列表,并在选择某一项时触发事件。 2.…...

使用Java创建RabbitMQ消息生产者的详细指南

目录 在现代分布式系统中,消息队列是实现异步通信的重要工具。RabbitMQ作为一种流行的开源消息代理,支持多种消息协议,广泛应用于微服务架构和事件驱动的应用程序中。本文将深入探讨如何使用Java创建RabbitMQ的消息生产者,发送消息…...

【LC】160. 相交链表

题目描述: 给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null 。 图示两个链表在节点 c1 开始相交: 题目数据 保证 整个链式结构中不存在环。 注意&…...

Spark架构及运行流程

Spark架构图 Driver: 解析用户的应用程序代码,转化为作业(job)。创建SparkContext上下文对象,其负责与资源管理器(ClusterManager)通信,进行资源的申请、任务的分配和监控等。跟踪Executor的执行情况。可通过UI界面查询运行情况。…...

Linux安装Python2.7.5(centos自带同款)

卸载已安装的python,防止版本兼容问题 rpm -qa|grep python|xargs rpm -ev --allmatches --nodeps 删除残余文件 whereis python |xargs rm -frv 安装前提是已安装gcc和g gcc --version g --version 下载安装python2.7.5 https://www.python.org/downloads/release/pyt…...

上传ssh公钥到目标服务器

创建密钥 ssh-keygen -t rsa -b 4096 -C "xxxx.xx"上传 sudo ssh-copy-id -i /Users/xx/.ssh/id_rsa.pub root127.0.0.1...

【LLMs】用LM Studio本地部署离线大语言模型

文章目录 一、下载LM Studio二、下载大语言模型1. 查看模型介绍2. 点击模型文件进行下载2.1 完整下载2.2 部分下载 三、加载模型1. 打开LM Studio图形化界面,点击**My Models**2. 然后,点击“...”,选择“change”,选择刚下载好的…...

SpringBoot下类加入容器的几种方式

SpringBoot下类加入容器的几种方式 在 Spring Boot 中,类加入容器的方式不仅多样,而且每种方式都有其特定的使用场景。以下是几种常见的将类加入 Spring 容器的方法及其适用场景: 1. 使用 Component 及其派生注解 使用场景:当开…...

【Mysql】忘记Root密码后如何不影响数据进行重置密码

方法一:通用方法--启动时跳过权限表 1> 停止数据库 以管理员方式打开cmd!! C:\Users\Administrator>net stop mysql MySQL 服务正在停止.. MySQL 服务已成功停止。 2> 启动时跳过权限表 mysqld --console --skip-grant-tables -…...

宝塔内设置redis后,项目以及RedisDesktopManager客户端连接不上!

项目展现问题: Unable to connect to Redis; nested exception is io.lettuce.core.RedisConnectionException: Unable to connect to xxx.宝塔外链.ip.xxxx:6379 redis客户端连接失败: 1、宝塔中确认redis端口已放行 2、修改redis的配置 bind&#x…...

一文了解模式识别顶会ICPR 2024的研究热点与最新趋势

简介 对模式识别研究领域前沿方向的跟踪是提高科研能力和制定科研战略的关键。本文通过图文并茂的方式介绍了ICPR 2024的研究热点与最新趋势,帮助读者了解和跟踪模式识别的前沿研究方向。本推文的作者是黄星宇,审校为邱雪和许东舟。 一、会议介绍 ICPR…...

【深度学习】深刻理解BERT

BERT(Bidirectional Encoder Representations from Transformers)是由Google于2018年提出的一种预训练的语言表示模型,它基于Transformer架构并能够处理自然语言处理(NLP)中的多种任务。BERT的核心创新是其使用了双向编…...

UE5 学习系列(三)创建和移动物体

这篇博客是该系列的第三篇,是在之前两篇博客的基础上展开,主要介绍如何在操作界面中创建和拖动物体,这篇博客跟随的视频链接如下: B 站视频:s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...

Cinnamon修改面板小工具图标

Cinnamon开始菜单-CSDN博客 设置模块都是做好的,比GNOME简单得多! 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...

dify打造数据可视化图表

一、概述 在日常工作和学习中,我们经常需要和数据打交道。无论是分析报告、项目展示,还是简单的数据洞察,一个清晰直观的图表,往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server,由蚂蚁集团 AntV 团队…...

今日学习:Spring线程池|并发修改异常|链路丢失|登录续期|VIP过期策略|数值类缓存

文章目录 优雅版线程池ThreadPoolTaskExecutor和ThreadPoolTaskExecutor的装饰器并发修改异常并发修改异常简介实现机制设计原因及意义 使用线程池造成的链路丢失问题线程池导致的链路丢失问题发生原因 常见解决方法更好的解决方法设计精妙之处 登录续期登录续期常见实现方式特…...

【LeetCode】3309. 连接二进制表示可形成的最大数值(递归|回溯|位运算)

LeetCode 3309. 连接二进制表示可形成的最大数值(中等) 题目描述解题思路Java代码 题目描述 题目链接:LeetCode 3309. 连接二进制表示可形成的最大数值(中等) 给你一个长度为 3 的整数数组 nums。 现以某种顺序 连接…...

零知开源——STM32F103RBT6驱动 ICM20948 九轴传感器及 vofa + 上位机可视化教程

STM32F1 本教程使用零知标准板(STM32F103RBT6)通过I2C驱动ICM20948九轴传感器,实现姿态解算,并通过串口将数据实时发送至VOFA上位机进行3D可视化。代码基于开源库修改优化,适合嵌入式及物联网开发者。在基础驱动上新增…...

第八部分:阶段项目 6:构建 React 前端应用

现在,是时候将你学到的 React 基础知识付诸实践,构建一个简单的前端应用来模拟与后端 API 的交互了。在这个阶段,你可以先使用模拟数据,或者如果你的后端 API(阶段项目 5)已经搭建好,可以直接连…...

数据结构第5章:树和二叉树完全指南(自整理详细图文笔记)

名人说:莫道桑榆晚,为霞尚满天。——刘禹锡(刘梦得,诗豪) 原创笔记:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 上一篇:《数据结构第4章 数组和广义表》…...

Java并发编程实战 Day 11:并发设计模式

【Java并发编程实战 Day 11】并发设计模式 开篇 这是"Java并发编程实战"系列的第11天,今天我们聚焦于并发设计模式。并发设计模式是解决多线程环境下常见问题的经典解决方案,它们不仅提供了优雅的设计思路,还能显著提升系统的性能…...

RushDB开源程序 是现代应用程序和 AI 的即时数据库。建立在 Neo4j 之上

一、软件介绍 文末提供程序和源码下载 RushDB 改变了您处理图形数据的方式 — 不需要 Schema,不需要复杂的查询,只需推送数据即可。 二、Key Features ✨ 主要特点 Instant Setup: Be productive in seconds, not days 即时设置 :在几秒钟…...