Spring 如何在单元测试中使用会话?
我有一个spring服务方法,它获取会话中存储的对象(使用FacesContext),如下所示:Spring 如何在单元测试中使用会话?,spring,unit-testing,jakarta-ee,jsf-2,junit,Spring,Unit Testing,Jakarta Ee,Jsf 2,Junit,我有一个spring服务方法,它获取会话中存储的对象(使用FacesContext),如下所示: (MyObject)((HttpServletRequest) FacesContext .getCurrentInstance().getExternalContext().getRequest()) .getSession().getAttribute("myObject"); 我想在调用该方法之前,在单元测试中将该对象放入会话中
(MyObject)((HttpServletRequest) FacesContext
.getCurrentInstance().getExternalContext().getRequest())
.getSession().getAttribute("myObject");
我想在调用该方法之前,在单元测试中将该对象放入会话中
所以我在这篇文章中尝试了这个解决方案:
在我的测试方法中,我在调用服务之前将对象放在会话中,但是服务在试图从会话中获取对象时抛出异常,我猜这是因为facescontext不可用,你认为呢
我使用的是Spring,Junit,JSF2,请告知,谢谢。我假设您正在谈论HttpSession 创建一个模拟会话,告诉模拟会话在使用被测试对象使用的名称调用其getAttribute方法时始终返回此对象,并将此模拟会话而不是真实会话传递给被测试对象 模仿诸如Mockito或EasyMock之类的API将有助于做到这一点 编辑:假设要测试的方法如下所示:
public String foo() {
// some lines of code
MyObject o =
(MyObject)((HttpServletRequest) FacesContext
.getCurrentInstance().getExternalContext().getRequest())
.getSession().getAttribute("myObject");
// some more lines of code, using o.
}
public String foo() {
// some lines of code
MyObject o = getMyObjectFromSession();
// some more lines of code, using o.
}
protected MyObject getMyObjectFromSession() {
return (MyObject)((HttpServletRequest) FacesContext
.getCurrentInstance().getExternalContext().getRequest())
.getSession().getAttribute("myObject");
}
您可以像这样重构它:
public String foo() {
// some lines of code
MyObject o =
(MyObject)((HttpServletRequest) FacesContext
.getCurrentInstance().getExternalContext().getRequest())
.getSession().getAttribute("myObject");
// some more lines of code, using o.
}
public String foo() {
// some lines of code
MyObject o = getMyObjectFromSession();
// some more lines of code, using o.
}
protected MyObject getMyObjectFromSession() {
return (MyObject)((HttpServletRequest) FacesContext
.getCurrentInstance().getExternalContext().getRequest())
.getSession().getAttribute("myObject");
}
然后,您可以使用模拟框架执行以下操作(伪代码):
添加到您的测试类路径,它将为您提供org.springframework.mock.web.MockHttpSession
。这是一个非常简单的实现,您可以使用new
创建它,而无需使用JavaEE容器
JAR还包含请求、响应和其他所有内容的模拟
另一个解决方案是使用与此相同的方法。使用Spring3.2,这非常容易
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(...)
@WebAppConfiguration
public class SessionTest {
@Autowired
MockHttpSession session;
@Test
public void sessionAttributeTest() throws Exception {
MyObject myObject = session.getAttribute("myObject");
...
}
}
更多信息:如何访问生产代码中的会话?注射?从HTTP请求?Session scope?这里是一个使用Session的示例,我猜您真正想要测试的代码是调用FacesContext前后的代码。如果是这样,将对FacesContext的调用外部化为一个受保护的帮助器方法或对象,模拟该帮助器方法/对象,使其返回您想要的任何内容,并测试代码。否,如上所述,我想从服务中的会话中获取对象,当从单元测试调用服务时,运行应用程序时,它工作正常,但在调用单元测试时给出空指针。我想看看这个用法的完整示例。我可以创建一个
MockHttpSession
。但是,对MockHttpSession.invalidate()
的任何调用都会引发异常,表示会话已无效…并且发言过快。我正在使会话无效,然后尝试一个session.getAttribute()
,希望它返回null。相反,它抛出非法状态异常
,因为会话已经无效。