使用 Mockito 模拟 HttpSession
Mocking HttpSession using Mockito
我需要测试以下控制器方法:
@RequestMapping(value="/addLocation")
public String addLocation(HttpServletRequest request, HttpSession session) {
String location = (String) request.getParameter("plz_ort");
String radius = (String) request.getParameter("umkreis");
((ArrayList<String>) session.getAttribute("queryTopics")).clone();
...
}
因此我使用 Mockito 和 JUnit
编写了这个测试 class
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import java.util.ArrayList;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mock.web.MockHttpSession;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
public class MyControllerTest {
@InjectMocks
private MyController myController;
private MockMvc mockMvc;
@InjectMocks
MockHttpSession session;
@Before
public void setup() {
// Process mock annotations
MockitoAnnotations.initMocks(this);
// Setup Spring test in standalone mode
this.mockMvc = MockMvcBuilders.standaloneSetup(MyController)
.build();
}
@Test
public void addLocation_StatusOK() throws Exception {
session.setAttribute("queryTopics", new ArrayList<String>(0));
this.mockMvc.perform(
post("/addLocation")
.param("plz_ort", "PLZ ORT")
.param("umkreis", "5"))
.andExpect(
status().isOk());
}
}
如您所见,我需要在 运行 此测试时模拟会话。
当我调试代码并停在 session.setAttribute("queryTopics", new ArrayList<String>(0));
行时,会话对象是 org.springframework.mock.web.MockHttpSession@5583d693
(包含属性散列映射 {queryTopics=[]}
),所以我认为这很好。
然而,我在 ((ArrayList<String>) session.getAttribute("queryTopics")).clone();
行的下一个断点的会话对象是 org.springframework.mock.web.MockHttpSession@7545a27f
.
至少它是正确的类型 (MockHttpSession
),但它有一个不同的 ID,因此它实际上是一个全新的对象,因此不包含测试中的会话属性。
你能帮我解决这个问题吗?
模拟 MVC 将创建一个 spring 模拟请求和一个 spring 模拟会话,然后调用您的控制器方法。为了在调用控制器方法之前在会话中设置一些状态,您需要 configure the mock request 使用构建器:
public class MyControllerTest {
@InjectMocks
private MyController myController;
private MockMvc mockMvc;
@Before
public void setup() {
// Process mock annotations
MockitoAnnotations.initMocks(this);
// Setup Spring test in standalone mode
this.mockMvc = MockMvcBuilders.standaloneSetup(MyController)
.build();
}
@Test
public void addLocation_StatusOK() throws Exception {
this.mockMvc.perform(
post("/addLocation")
.param("plz_ort", "PLZ ORT")
.param("umkreis", "5")
.sessionAttr("queryTopics", new ArrayList<String>(0))
.andExpect(
status().isOk());
}
}
我需要测试以下控制器方法:
@RequestMapping(value="/addLocation")
public String addLocation(HttpServletRequest request, HttpSession session) {
String location = (String) request.getParameter("plz_ort");
String radius = (String) request.getParameter("umkreis");
((ArrayList<String>) session.getAttribute("queryTopics")).clone();
...
}
因此我使用 Mockito 和 JUnit
编写了这个测试 classimport static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import java.util.ArrayList;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mock.web.MockHttpSession;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
public class MyControllerTest {
@InjectMocks
private MyController myController;
private MockMvc mockMvc;
@InjectMocks
MockHttpSession session;
@Before
public void setup() {
// Process mock annotations
MockitoAnnotations.initMocks(this);
// Setup Spring test in standalone mode
this.mockMvc = MockMvcBuilders.standaloneSetup(MyController)
.build();
}
@Test
public void addLocation_StatusOK() throws Exception {
session.setAttribute("queryTopics", new ArrayList<String>(0));
this.mockMvc.perform(
post("/addLocation")
.param("plz_ort", "PLZ ORT")
.param("umkreis", "5"))
.andExpect(
status().isOk());
}
}
如您所见,我需要在 运行 此测试时模拟会话。
当我调试代码并停在 session.setAttribute("queryTopics", new ArrayList<String>(0));
行时,会话对象是 org.springframework.mock.web.MockHttpSession@5583d693
(包含属性散列映射 {queryTopics=[]}
),所以我认为这很好。
然而,我在 ((ArrayList<String>) session.getAttribute("queryTopics")).clone();
行的下一个断点的会话对象是 org.springframework.mock.web.MockHttpSession@7545a27f
.
至少它是正确的类型 (MockHttpSession
),但它有一个不同的 ID,因此它实际上是一个全新的对象,因此不包含测试中的会话属性。
你能帮我解决这个问题吗?
模拟 MVC 将创建一个 spring 模拟请求和一个 spring 模拟会话,然后调用您的控制器方法。为了在调用控制器方法之前在会话中设置一些状态,您需要 configure the mock request 使用构建器:
public class MyControllerTest {
@InjectMocks
private MyController myController;
private MockMvc mockMvc;
@Before
public void setup() {
// Process mock annotations
MockitoAnnotations.initMocks(this);
// Setup Spring test in standalone mode
this.mockMvc = MockMvcBuilders.standaloneSetup(MyController)
.build();
}
@Test
public void addLocation_StatusOK() throws Exception {
this.mockMvc.perform(
post("/addLocation")
.param("plz_ort", "PLZ ORT")
.param("umkreis", "5")
.sessionAttr("queryTopics", new ArrayList<String>(0))
.andExpect(
status().isOk());
}
}