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

使用MockMVC时无法读取application.yml配置值的问题求助

问题描述
  • 使用MockMVC测试API时,接口内部读取application.yml配置值为空,触发NullPointerException
  • 不使用MockMVC测试GET接口功能正常,但该方式不支持MultipartFile作为请求体
  • 尝试自动装配WebAppContext并使用webAppContextSetup()时,抛出NullValueException,提示未找到WebAppContext

测试代码如下:

@AutoConfigureMockMvc
@ExtendWith(SpringExtension.class)
@WebMvcTest(MyController.class)
@SpringBootTest
public class MyControllerTest {

    private String token = null;
    private String url=null;
    MockMvc mockMvc;
    public CceControllerTest() {
        GenerateTokenTest generateToken = new GenerateTokenTest();
        try {
            this.url = TestingConstant.ip +TestingConstant.port + "cce";
            this.token=generateToken.getToken();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    
     @Before
        public void before() {
            MockitoAnnotations.openMocks(this);
            mockMvc = MockMvcBuilders.standaloneSetup(new MyController()).build();
        }
     
   
    @Test
    public void getdata() {
        try {
            String u = this.url + "/getdata";
            
            mockMvc.perform(
                    MockMvcRequestBuilders.get(u).header("Authorization", "Bearer" + token))
                    .andExpect(MockMvcResultMatchers.status().isOk());
            
            
            
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    @Test
    public void excelImportNew() {
        try {
            String apiUrl = this.url + "/excelImportNew";
            MockMultipartFile file = new MockMultipartFile("file", "test.csv", "text/csv", "CSV content".getBytes());
            String State = "Himachal Pradesh";
            String District = "Hamirpur";
            String userName = "abcd";
            mockMvc.perform(
                    MockMvcRequestBuilders.multipart(apiUrl).file(file).header("Authorization", "Bearer" + token)
                            .param("State", State).param("District", District).param("userName", userName))
                    .andExpect(MockMvcResultMatchers.status().isOk())
                    .andExpect(MockMvcResultMatchers.content().string("File uploaded successfully"));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
     
    
}
解决方案

1. 修复注解冲突

移除@WebMvcTest和@ExtendWith(SpringExtension.class),仅保留@SpringBootTest和@AutoConfigureMockMvc。

  • @WebMvcTest是切片测试注解,仅加载控制器层相关组件,不会初始化完整Spring上下文,导致配置文件无法被读取;@SpringBootTest会启动完整的Spring应用上下文,配合@AutoConfigureMockMvc可自动配置MockMvc实例,确保配置能正常加载。

2. 正确注入MockMvc

删除@Before方法中手动创建MockMvc的逻辑,直接通过@Autowired注入Spring容器管理的MockMvc实例:

@Autowired
private MockMvc mockMvc;

手动通过standaloneSetup创建的MockMvc实例脱离Spring上下文,无法读取配置类中的值,这是导致NPE的直接原因。

3. 修正请求路径

MockMVC是模拟请求,无需拼接完整IP和端口,直接使用接口的相对路径即可,比如将/cce/getdata作为请求路径,而非完整的http://ip:port/cce/getdata。

4. 调整初始化逻辑

将构造方法中的token和url初始化逻辑移至@BeforeEach方法(替代旧的@Before),避免构造方法执行时Spring上下文未完全加载的问题:

@BeforeEach
void setUp() {
    GenerateTokenTest generateToken = new GenerateTokenTest();
    try {
        this.url = "/cce"; // 仅保留相对路径前缀
        this.token = generateToken.getToken();
    } catch (Exception e) {
        e.printStackTrace();
    }
    MockitoAnnotations.openMocks(this);
}

修改后的完整测试代码

@AutoConfigureMockMvc
@SpringBootTest
public class MyControllerTest {

    private String token = null;
    private String url = null;

    @Autowired
    private MockMvc mockMvc;

    @BeforeEach
    void setUp() {
        GenerateTokenTest generateToken = new GenerateTokenTest();
        try {
            this.url = "/cce";
            this.token = generateToken.getToken();
        } catch (Exception e) {
            e.printStackTrace();
        }
        MockitoAnnotations.openMocks(this);
    }

    @Test
    public void getdata() {
        try {
            String u = this.url + "/getdata";

            mockMvc.perform(MockMvcRequestBuilders.get(u)
                            .header("Authorization", "Bearer " + token)) // Bearer后加空格,符合规范
                    .andExpect(MockMvcResultMatchers.status().isOk());

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Test
    public void excelImportNew() {
        try {
            String apiUrl = this.url + "/excelImportNew";
            MockMultipartFile file = new MockMultipartFile("file", "test.csv", "text/csv", "CSV content".getBytes());
            String state = "Himachal Pradesh";
            String district = "Hamirpur";
            String userName = "abcd";

            mockMvc.perform(MockMvcRequestBuilders.multipart(apiUrl)
                            .file(file)
                            .header("Authorization", "Bearer " + token)
                            .param("State", state)
                            .param("District", district)
                            .param("userName", userName))
                    .andExpect(MockMvcResultMatchers.status().isOk())
                    .andExpect(MockMvcResultMatchers.content().string("File uploaded successfully"));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

额外提示:注意Authorization头中Bearer与token之间需要加空格,否则可能导致鉴权失败。

内容的提问来源于stack exchange,提问作者Meghana Tulla

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 13:25:39