单元测试 Spring MissingServletRequestParameterException JSON 响应

2023-12-28

我在 Spring boot 休息控制器中有 POST 方法,如下所示

@RequestMapping(value="/post/action/bookmark", method=RequestMethod.POST)
public @ResponseBody Map<String, String> bookmarkPost(
        @RequestParam(value="actionType",required=true) String actionType,
        @RequestParam(value="postId",required=true) String postId,
        @CurrentUser User user) throws Exception{
    return service.bookmarkPost(postId, actionType, user);
}

现在如果我测试缺少参数Postman我收到 400 http 响应和 JSON 正文:

{
  "timestamp": "2015-07-20",
  "status": 400,
  "error": "Bad Request",
  "exception": "org.springframework.web.bind.MissingServletRequestParameterException",
  "message": "Required String parameter 'actionType' is not present",
  "path": "/post/action/bookmark"
}

到目前为止还可以,但是当我尝试进行单元测试时,我没有收到 JSON 响应

@Test
public void bookmarkMissingActionTypeParam() throws Exception{
    // @formatter:off
    mockMvc.perform(
                post("/post/action/bookmark")
                    .accept(MediaType.APPLICATION_JSON)
                    .param("postId", "55ab8831036437e96e8250b6")
                    )
            .andExpect(status().isBadRequest())
            .andExpect(jsonPath("$.exception", containsString("MissingServletRequestParameterException")));
    // @formatter:on
}

测试失败并产生

java.lang.IllegalArgumentException: json can not be null or empty

I did a .andDo(打印())发现响应中没有body

MockHttpServletResponse:
          Status = 400
   Error message = Required String parameter 'actionType' is not present
         Headers = {X-Content-Type-Options=[nosniff], X-XSS-Protection=[1; mode=block], Cache-Control=[no-cache, no-store], Pragma=[no-cache], Expires=[1], X-Frame-Options=[DENY]}
    Content type = null
            Body = 
   Forwarded URL = null
  Redirected URL = null
         Cookies = []

为什么我在对控制器进行单元测试时没有收到 JSON 响应,但在使用 Postman 或 cUrl 的手动测试中收到它?

编辑:我已经添加@WebIntegrationTest但得到了同样的错误:

import static org.hamcrest.Matchers.containsString;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.boot.test.WebIntegrationTest;
import org.springframework.http.MediaType;
import org.springframework.security.web.FilterChainProxy;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = RestApplication.class)
@WebIntegrationTest
public class PostControllerTest {

    private MockMvc mockMvc;

    @Autowired
    private WebApplicationContext webApplicationContext;

    @Autowired
    private FilterChainProxy springSecurityFilterChain;

    @Before
    public void setUp() {
        mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext)
                .addFilter(springSecurityFilterChain)
                .build();
    }  

    @Test
    public void bookmarkMissingActionTypeParam() throws Exception{
        // @formatter:off
        mockMvc.perform(
                    post("/post/action/bookmark")
                        .accept(MediaType.APPLICATION_JSON)
                        .param("postId", "55ab8831036437e96e8250b6")
                        )
                .andDo(print())
                .andExpect(status().isBadRequest())
                .andExpect(jsonPath("$.exception", containsString("MissingServletRequestParameterException")));
        // @formatter:on
    }
}

这是因为 Spring Boot 自动配置了异常处理程序org.springframework.boot.autoconfigure.web.BasicErrorController这可能不存在于您的单元测试中。获取它的一种方法是使用 Spring Boot 测试支持相关注释:

@SpringApplicationConfiguration
@WebIntegrationTest

更多细节是here http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#boot-features-testing-spring-boot-applications

Update: 你是绝对正确的,UI 中的行为与测试中的行为非常不同,响应状态代码的错误页面在非 servlet 测试环境中未正确连接。改进这种行为对于 Spring MVC 和/或 Spring Boot 来说可能是一个很好的 bug。

现在,我有一个解决方法可以模拟BasicErrorController通过以下方式:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = {RestApplication.class, TestConfiguration.class})
@WebIntegrationTest
public class PostControllerTest {

    private MockMvc mockMvc;

    @Autowired
    private WebApplicationContext webApplicationContext;

    @Autowired
    private FilterChainProxy springSecurityFilterChain;

    @Before
    public void setUp() {
        mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext)
                .addFilter(springSecurityFilterChain)
                .build();
    }  

    @Test
    public void bookmarkMissingActionTypeParam() throws Exception{
        // @formatter:off
        mockMvc.perform(
                    post("/post/action/bookmark")
                        .accept(MediaType.APPLICATION_JSON)
                        .param("postId", "55ab8831036437e96e8250b6")
                        )
                .andDo(print())
                .andExpect(status().isBadRequest())
                .andExpect(jsonPath("$.exception", containsString("MissingServletRequestParameterException")));
        // @formatter:on
    }
}
     @Configuration
    public static class TestConfiguration {


        @Bean
        public ErrorController errorController(ErrorAttributes errorAttributes) {
            return new ErrorController(errorAttributes);
        }
    }
@ControllerAdvice
class ErrorController extends BasicErrorController {

    public ErrorController(ErrorAttributes errorAttributes) {
        super(errorAttributes);
    }

    @Override
    @ExceptionHandler(Exception.class)
    @ResponseBody
    public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) {
        return super.error(request);
    }
}

我在这里做的是添加一个ControllerAdvice它处理异常流并将委托返回给BasicErrorController。这至少会让你的行为保持一致。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

单元测试 Spring MissingServletRequestParameterException JSON 响应 的相关文章

  • 线程自动利用多个CPU核心?

    假设我的应用程序运行 2 个线程 例如渲染线程和游戏更新线程 如果它在具有多核 CPU 当今典型 的移动设备上运行 我是否可以期望线程在可能的情况下自动分配给不同的核心 我知道底层操作系统内核 Android linux内核 决定调度 我的
  • Android Studio 在编译时未检测到支持库

    由于 Android Studio 将成为 Android 开发的默认 IDE 因此我决定将现有项目迁移到 Android studio 中 项目结构似乎不同 我的项目中的文件夹层次结构如下 Complete Project gt idea
  • 解决错误:日志已在具有多个实例的atomikos中使用

    我仅在使用atomikos的实时服务器上遇到问题 在我的本地服务器上它工作得很好 我在服务器上面临的问题是 init 中出错 日志已在使用中 完整的异常堆栈跟踪 java lang RuntimeException Log already
  • manifest.mf 文件的附加内容的约定?

    Java JAR 中的 MANIFEST MF 文件是否有任何超出 MANIFEST MF 约定的约定 JAR规范 http download oracle com javase 1 4 2 docs guide jar jar html
  • JNI 不满意链接错误

    我想创建一个简单的 JNI 层 我使用Visual studio 2008创建了一个dll Win 32控制台应用程序项目类型 带有DLL作为选项 当我调用本机方法时 出现此异常 Exception occurred during even
  • 如何查找 Android 设备中的所有文件并将它们放入列表中?

    我正在寻求帮助来列出 Android 外部存储设备中的所有文件 我想查找所有文件夹 包括主文件夹的子文件夹 有办法吗 我已经做了一个基本的工作 但我仍然没有得到想要的结果 这不起作用 这是我的代码 File files array file
  • java.io.IOException: %1 不是有效的 Win32 应用程序

    我正在尝试对 XML 文档进行数字签名 为此我有两个选择 有一个由爱沙尼亚认证中心为程序员创建的库 还有一个由银行制作的运行 Java 代码的脚本 如果使用官方 认证中心 库 那么一切都会像魅力一样进行一些调整 但是当涉及到银行脚本时 它会
  • Convert.FromBase64String 方法的 Java 等效项

    Java 中是否有相当于Convert FromBase64String http msdn microsoft com en us library system convert frombase64string aspx which 将指
  • HDFS:使用 Java / Scala API 移动多个文件

    我需要使用 Java Scala 程序移动 HDFS 中对应于给定正则表达式的多个文件 例如 我必须移动所有名称为 xml从文件夹a到文件夹b 使用 shell 命令我可以使用以下命令 bin hdfs dfs mv a xml b 我可以
  • 如何为 Gson 编写自定义 JSON 反序列化器?

    我有一个 Java 类 用户 public class User int id String name Timestamp updateDate 我收到一个包含来自 Web 服务的用户对象的 JSON 列表 id 1 name Jonas
  • hibernate总是自己删除表中的所有数据

    您好 我正在开发一个 spring mvc 应用程序 它使用 hibernate 连接到存储文件的 mysql 数据库 我有两个方法 一个方法添加我选择的特定文件路径中的所有文件 另一种方法调用查询以返回从 mysql 存储的文件列表 问题
  • OnClick 事件中的 finish() 如何工作?

    我有一个Activity一键退出Activity 通过layout xml我必须设置OnClick事件至cmd exit调用 this finish 效果很好 public void cmd exit View editLayout thi
  • Prim 的迷宫生成算法:获取相邻单元格

    我基于 Prim 算法编写了一个迷宫生成器程序 该算法是 Prim 算法的随机版本 从充满墙壁的网格开始 选择一个单元格 将其标记为迷宫的一部分 将单元格的墙壁添加到墙壁列表中 While there are walls in the li
  • 迁移到 java 17 后有关“每个进程的内存映射”和 JVM 崩溃的 GC 警告

    我们正在将 java 8 应用程序迁移到 java 17 并将 GC 从G1GC to ZGC 我们的应用程序作为容器运行 这两个基础映像之间的唯一区别是 java 的版本 例如对于 java 17 版本 FROM ubuntu 20 04
  • 序列化对象以进行单元测试

    假设在单元测试中我需要一个对象 其中所有 50 个字段都设置了一些值 我不想手动设置所有这些字段 因为这需要时间而且很烦人 不知何故 我需要获得一个实例 其中所有字段都由一些非空值初始化 我有一个想法 如果我要调试一些代码 在某个时候我会得
  • 反思 Groovy 脚本中声明的函数

    有没有一种方法可以获取 Groovy 脚本中声明的函数的反射数据 该脚本已通过GroovyShell目的 具体来说 我想枚举脚本中的函数并访问附加到它们的注释 Put this到 Groovy 脚本的最后一行 它将作为脚本的返回值 a la
  • 使用 AWS Java SDK 为现有 S3 对象设置 Expires 标头

    我正在更新 Amazon S3 存储桶中的现有对象以设置一些元数据 我想设置 HTTPExpires每个对象的标头以更好地处理 HTTP 1 0 客户端 我们正在使用AWS Java SDK http aws amazon com sdkf
  • 使用 SAX 进行 XML 解析 |如何处理特殊字符?

    我们有一个 JAVA 应用程序 可以从 SAP 系统中提取数据 解析数据并呈现给用户 使用 SAP JCo 连接器提取数据 最近我们抛出了一个异常 org xml sax SAXParseException 字符引用 是无效的 XML 字符
  • 休眠以持久保存日期

    有没有办法告诉 Hibernate java util Date 应该持久保存 我需要这个来解决 MySQL 中缺少的毫秒分辨率问题 您能想到这种方法有什么缺点吗 您可以自己创建字段long 或者使用自定义的UserType 实施后User
  • 使用SpringApplication时加载applicationcontext.xml

    谁能提供加载 applicationContext xml 文件的 SpringApplication 示例 我正在尝试使用以下方法将我的 GWT RPC 应用程序移动到 RESTful Web 服务春天的例子 https spring i

随机推荐

  • 如何计算CNN的权重个数?

    考虑到用于将图像分为两类的卷积神经网络 我们如何计算权重数量 输入 100x100 灰度图像 LAYER 1 具有 60 个 7x7 卷积滤波器的卷积层 stride 1 有效 填充 LAYER 2 具有 100 个 5x5 卷积滤波器的卷
  • inner() 为参数“ax”获取了多个值

    在带有 Python 的 Jupyter 笔记本中 我正在从数据帧的两列绘制六边形联合图 该图绘制正确 但我无法调整图片大小 这是代码 fig ax plt subplots fig set size inches 11 7 8 27 sn
  • 如何使用反射调用java中的方法

    如何使用反射调用带参数的方法 我想指定这些参数的值 下面是使用涉及原语的反射来调用方法的简单示例 import java lang reflect public class ReflectionExample public int test
  • Android Smack 聊天客户端

    嗨 朋友们 我正在使用从以下网址下载的 Smack3 2 1 jar http www igniterealtime org downloads index jsp http www igniterealtime org downloads
  • 如何在 terraform 中使用嵌套循环

    我正在尝试使用 Terraform count 在 Azure 中创建 3 个虚拟机 每个虚拟机需要多个磁盘 有什么办法可以做到这一点吗 我尝试创建磁盘名称和大小的映射 但收到错误 无法同时使用 count 和 for each resou
  • Pickle Spark RDD 并将其读入 Python

    我正在尝试通过 pickle 来序列化 Spark RDD 并将 pickled 文件直接读入 Python a sc parallelize 1 2 3 4 5 a saveAsPickleFile test pkl 然后 我将 test
  • 类构造函数中选项对象的默认值

    我创建了一个类 我想为值设置一些默认选项 以防用户不提供任何参数 我最近使用了一个将多个参数传递给一个对象的构造函数 因为我相信当用户创建该类的新实例时 它有助于提高可读性 这是我之前的做法 module exports class Use
  • 根据 codeigniter 中的用户角色重定向到管理员和用户

    如果管理员正在登录 我希望他进入管理 仪表板 否则到用户仪表板 登录控制器如下 在用户表中 我有一列 角色 值为 1 和 2 1 代表管理员 2 代表用户 并且有单独的角色表 登录用户功能 public function login dat
  • 我可以将 MongoDB 配置为内存吗?

    我有兴趣使用一个能够实现高性能的数据库 并且预期需要集群进行大规模水平扩展 我们正在考虑使用 MongoDB 有谁知道我是否可以在内存中使用它 即在 RAM 中 出于性能原因 Tnx 截至今天 最新版本的 MongoDB 即 v3 4 在其
  • 使用OpenCV的Sobel运算计算图像梯度方向

    我正在尝试使用 OpenCV 的 Sobel 方法的结果来确定图像梯度方向 我知道这应该是一个非常简单的任务 我想我理解这个理论 但实现它比我想象的更具挑战性 我希望渐变方向在 0 360 度之间 但我的代码显示所有渐变都在 180 270
  • 如何从离开网站警报中获取文本?

    如何从离开网站警报中获取文本 我尝试使用切换到它driver switchTo alert 但我收到空白文本 I have also attached screenshot of alert 请在这方面帮助我 下面是我的代码 public
  • 既然 BluetoothAdapter.getDefaultAdapter() 已被弃用,我该使用什么?

    How do I fix the deprecation warning in this code Alternatively are there any other options for doing this val mBluetoot
  • Power BI:计算无法正常工作

    我有一个包含资源名称 资源所有者 项目名称 项目经理 工作量的表 对于每个资源所有者 我想计算借出的工作量 所有者的资源在除所有者项目之外的项目中花费的工作量 和借用的工作量 所有者的资源在除项目所有者之外的其他项目中花费的工作量 For
  • 从 Groovy 中的字符串中删除空格

    我有一个像这样的字符串 String str My name is Monda 我怎样才能实现像这样的字符串 str MynameisMonda 您可以使用replaceAll http docs groovy lang org lates
  • UITableView,如何捕捉动画结束?

    我有一个包含很多行的 UITableView 它就像一个手风琴 http docs jquery com UI Accordion http docs jquery com UI Accordion主单元有子单元 子单元也有子单元 所以这是
  • 使正则表达式准确匹配点文件

    所以我已经达到了我的正则表达式能力的极限 我这里有一个 python 正则表达式 用于将文件路径或文件 uri 与各个部分的命名捕获组相匹配 它似乎是工作文件 除了点文件 MATCH PATH re compile r P
  • 为什么 getNetworkOperator 对于 CDMA 不可靠?

    谁能说出为什么文档getNetworkOperator的函数TelephonyManager指出这可能会返回 CDMA 不可靠的结果 获取网络操作员文档 http developer android com reference androi
  • 如何检测视图元素何时在 Angular 中渲染?

    我的设置是一个带有可单击行的 Angular Material 数据表 单击一行时 其内容会内联显示在textarea进行编辑 我唯一的问题是 我尝试将输入焦点移动到显示的textarea 我尝试使用 ViewChild 但稍后会在单击处理
  • 删除分片分配过滤器

    我设置了一个分片分配过滤器 例如 PUT cluster settings transient cluster routing allocation exclude name node 1 如何删除或禁用此类设置 我尝试使用包含 但随后我设
  • 单元测试 Spring MissingServletRequestParameterException JSON 响应

    我在 Spring boot 休息控制器中有 POST 方法 如下所示 RequestMapping value post action bookmark method RequestMethod POST public ResponseB