Junit4 模拟requert请求进行测试

本文介绍了一个关于在线用户管理功能的单元测试实现,使用Spring框架和Mock对象进行测试准备,重点在于如何设置Mock请求和响应对象,并利用这些对象来初始化在线用户会话。
package com.hytera.mrps.util;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath*:/spring.xml"})
public class OnlineUsersTest {
    private MockHttpServletRequest request;
    private MockHttpServletResponse response;
    
    @Before  
    public void setUp(){
        request = new MockHttpServletRequest();    
        request.setCharacterEncoding("UTF-8");    
        response = new MockHttpServletResponse();
    }
    @Test
    public void test() {
        HttpSession session = request.getSession(true);
        session.setAttribute("mock", new OnlineUsers());
    }
}

<think>在Spring MVC中,测试Controller通常使用Spring Test框架结合JUnit 4。我们可以使用`MockMvc`来模拟HTTP请求并验证响应。以下是一个示例,展示如何测试一个Spring MVC的Controller。 步骤: 1. 使用`@RunWith(SpringJUnit4ClassRunner.class)`来运行测试。 2. 使用`@WebAppConfiguration`注解表示测试需要加载Web应用程序上下文。 3. 使用`@ContextConfiguration`指定Spring配置类或XML配置文件的位置。 4. 注入`WebApplicationContext`。 5. 创建`MockMvc`对象,用于模拟HTTP请求。 6. 编写测试方法,使用`MockMvc`发起请求并验证结果。 假设我们有一个简单的Controller: ```java @Controller public class HelloController { @RequestMapping(value = "/hello", method = RequestMethod.GET) @ResponseBody public String sayHello() { return "Hello, World!"; } } ``` 测试类如下: ```java import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.web.context.WebApplicationContext; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; @RunWith(SpringJUnit4ClassRunner.class) @WebAppConfiguration @ContextConfiguration(classes = {AppConfig.class}) // 替换为你的配置类 public class HelloControllerTest { @Autowired private WebApplicationContext wac; private MockMvc mockMvc; @Before public void setup() { this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build(); } @Test public void testSayHello() throws Exception { mockMvc.perform(get("/hello")) .andExpect(status().isOk()) .andExpect(content().string("Hello, World!")); } } ``` 解释: - `@RunWith(SpringJUnit4ClassRunner.class)`:使用Spring的测试运行器。 - `@WebAppConfiguration`:表明这是一个Web应用测试,需要加载Web应用上下文。 - `@ContextConfiguration`:指定Spring配置,这里使用Java配置类`AppConfig.class`(请替换为你的配置类)。 - 在`setup()`方法中,通过`MockMvcBuilders.webAppContextSetup(wac).build()`初始化`MockMvc`。 - 在测试方法中,使用`mockMvc.perform(get("/hello"))`模拟GET请求,然后验证状态码为200,响应内容为"Hello, World!"。 注意:确保你的配置类(如`AppConfig`)正确配置了Spring MVC和扫描了Controller。 如果使用XML配置,`@ContextConfiguration`可以这样写: ```java @ContextConfiguration(locations = "classpath:spring-mvc-config.xml") // 指定XML配置文件 ``` 另外,如果Controller方法返回视图,你可能需要验证视图名称,例如: ```java .andExpect(view().name("helloView")) ``` 或者验证模型数据: ```java .andExpect(model().attribute("attrName", "value")) ``` **相关问题**: 1. 如何在Spring MVC测试模拟POST请求并提交表单数据? 2. 如何在测试模拟会话(Session)和请求参数? 3. 如何测试Spring MVC Controller中的异常处理? 4. 在Spring Boot中,如何使用JUnit 5(Jupiter)测试Controller? 注意:在Spring Boot中,通常使用`@SpringBootTest`和`@AutoConfigureMockMvc`来简化测试,但这里我们讨论的是非Boot的Spring MVC和JUnit4。</think>### Spring MVC 中 JUnit 4 测试 Controller 的完整指南 #### 核心实现代码 ```java import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.web.context.WebApplicationContext; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; @RunWith(SpringJUnit4ClassRunner.class) @WebAppConfiguration @ContextConfiguration(locations = { "classpath:spring-servlet.xml", // Controller 配置文件 "classpath:applicationContext.xml" // Service/DAO 配置文件 }) public class UserControllerTest { @Autowired private WebApplicationContext wac; private MockMvc mockMvc; @Before public void setup() { this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build(); } // 测试 GET 请求 @Test public void testGetUser() throws Exception { mockMvc.perform(get("/users/1")) // 模拟 GET 请求 .andExpect(status().isOk()) // 验证 HTTP 200 .andExpect(jsonPath("$.id").value(1)) // 验证 JSON 字段 .andExpect(jsonPath("$.name").value("John")); } // 测试 POST 请求 @Test public void testCreateUser() throws Exception { mockMvc.perform(post("/users") .contentType(MediaType.APPLICATION_JSON) .content("{\"name\":\"Alice\",\"email\":\"alice@example.com\"}")) .andExpect(status().isCreated()) .andExpect(header().string("Location", containsString("/users/2"))); } // 测试异常处理 @Test public void testUserNotFound() throws Exception { mockMvc.perform(get("/users/999")) .andExpect(status().isNotFound()) .andExpect(content().string("User not found")); } } ``` #### 关键组件解释 1. **`@RunWith(SpringJUnit4ClassRunner.class)`** - 原因:启用 Spring 测试上下文支持 - 作用:集成 Spring 容器与 JUnit 测试 2. **`@WebAppConfiguration`** - 原因:加载 Web 应用上下文(非普通应用上下文) - 作用:启用 Servlet 相关配置(Controller、拦截器等) 3. **`@ContextConfiguration`** - 原因:指定 Spring 配置文件位置 - 作用:初始化测试所需的 Bean(Controller/Service 等) - 注意:需替换为实际配置文件路径 4. **`MockMvc` 核心功能** - **模拟请求**:`perform(get()/post()/put()/delete())` - **验证响应**: - `status()`:HTTP 状态码 - `content()`:响应体内容 - `jsonPath()`:JSON 字段验证 - `header()`:响应头验证 - **请求构造**: - `contentType()`:设置 Content-Type - `content()`:设置请求体 - `param()`:设置 URL 参数 - `sessionAttr()`:设置会话属性 #### 常见问题及解决方案 1. **空指针异常(NullPointerException)** - **原因**:未正确加载 Spring 上下文 - **解决**:检查 `@ContextConfiguration` 路径是否正确 2. **404 状态码错误** - **原因**:URL 映射错误或 Controller 未扫描 - **解决**: ```java // 确保配置文件中包含组件扫描 @ContextConfiguration(locations = "classpath:spring-servlet.xml") // spring-servlet.xml 中应有: <context:component-scan base-package="com.example.controller"/> ``` 3. **JSON 解析失败** - **原因**:缺少 Jackson 依赖 - **解决**:添加 Maven 依赖: ```xml <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.13.0</version> </dependency> ``` 4. **Service 层依赖注入失败** - **原因**:测试未加载 Service 配置 - **解决**:在 `@ContextConfiguration` 中添加 Service 配置文件: ```java @ContextConfiguration(locations = { "classpath:spring-servlet.xml", "classpath:service-context.xml" // 添加 Service 配置 }) ``` #### 最佳实践建议 1. **使用独立测试配置** 创建 `test-spring-config.xml` 仅包含测试所需 Bean 2. **Mock 依赖服务** 结合 `@MockBean` 避免访问真实数据库: ```java @MockBean private UserService userService; @Before public void initMocks() { when(userService.getUser(1)).thenReturn(new User(1, "John")); } ``` 3. **验证逻辑而非实现** 聚焦于: - HTTP 状态码 - 响应内容结构 - 关键业务数据 避免过度验证内部实现细节 4. **测试异常流** 覆盖所有错误场景: ```java @Test public void testInvalidEmail() throws Exception { mockMvc.perform(post("/users") .content("{\"name\":\"Bob\",\"email\":\"invalid\"}")) .andExpect(status().isBadRequest()) .andExpect(jsonPath("$.errors[0]").value("Invalid email format")); } ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值