You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring2.7+JUnit5单元测试MockMvc contentType方法未定义报错

问题原因

报错和依赖缺失没有关系,是三处写法错误叠加导致的:

  • 核心错误:链式调用的括号位置写错了。contentType()、content()是请求构造器MockHttpServletRequestBuilder的方法,需要写在get()/post()的调用链上;你提前闭合了perform()方法的括号,相当于在perform()返回的ResultActions对象上调用这些方法,而ResultActions根本没有定义contentType方法,IDE自然提示方法未定义。
  • 测试框架注解混用:你导入的是JUnit5的@Test注解(包路径org.junit.jupiter.api.Test),但类上用的是JUnit4专属的@RunWith(SpringRunner.class),二者不兼容,即使修好链式调用问题,也会出现上下文加载失败的错误。
  • 请求方法不匹配:产品创建是写操作,标准实现用POST请求,你用get()构造了GET请求,即使语法正确,也会因为接口请求方法不匹配返回405错误。
  • 额外隐患:代码中用到的mockMvc、repo对象没有加对应注入注解,运行时会报空指针。
修复步骤
  1. 清理无效导入和错误注解:删除JUnit4相关的@RunWith注解和对应导入,JUnit5环境下@WebMvcTest已经内置了Spring测试扩展,不需要额外指定运行器。
  2. 修正MockMvc调用结构:把contentType、content等请求属性配置挪到请求构造器的调用链内部,最后再把完整的请求构造器传入perform()方法。
  3. 替换请求方法:把GET请求构造器换成POST,补全缺失的静态导入。
  4. 为依赖对象添加必要的注入注解。
修复后可运行代码

首先是导入部分,删除无效导入、补全缺失项:

import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectWriter;
// 替换成你自己项目中Product、Repository、Controller的实际包路径
import com.example.demo.entity.Product;
import com.example.demo.repository.ProductRepository;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;

测试类代码:

// 指定要测试的Controller类,避免加载全量Web上下文拖慢测试速度
@WebMvcTest(ProductController.class)
class RestControllerMvcTests {
    @Autowired
    private MockMvc mockMvc;

    @MockBean
    private ProductRepository repo;

    // 替换成你项目实际的接口路径、上下文路径
    private static final String PRODUCT_URL = "/product";
    private static final String CONTEXT_URL = "/api";

    @Test
    public void testCreateProduct() throws Exception {
        Product product = buildProduct();
        when(repo.save(any())).thenReturn(product);
        ObjectWriter objwrite = new ObjectMapper().writer().withDefaultPrettyPrinter();

        // 注意括号层级:所有请求配置都在post()的调用链上,最后再传入perform
        mockMvc.perform(post(PRODUCT_URL)
                        .contextPath(CONTEXT_URL)
                        .contentType(MediaType.APPLICATION_JSON)
                        .content(objwrite.writeValueAsString(product)))
                .andExpect(status().isOk());
    }

    private Product buildProduct() {
        Product product = new Product();
        // 补全测试对象的字段赋值
        return product;
    }
}
额外说明
  • 如果确实要测试GET接口,不要加.content()传递请求体,HTTP规范中GET请求不推荐携带请求体,不同容器对这类请求的处理逻辑不一致,容易出现偶发错误。
  • Spring Boot 2.7默认使用JUnit5作为测试框架,不要引入任何org.junit.runner、org.junit.Test开头的JUnit4相关类,避免出现框架兼容问题。

内容的提问来源于stack exchange,提问作者c513-oz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 14:21:12