有一个我想测试的servlet,servlet有 session 并将“loginBean”(其中包含登录的用户相关信息)放入 session 内,我已经模拟了它并且工作正常,现在在GUI级别,有2个选项卡,DetailSet1,detailsSet2,当你输入DetailSet1的数据时,它会保存在session中,并且还执行一些业务逻辑,现在来到DetailsSet2,你已经在session中拥有了DetailSet1,所以它得到了所需的一切,数据保存在DB中。现在很明显我必须模拟 HttpSession 因为我从容器外部运行单元案例,但是存储的数据也在 HttpSession 中,如果我也模拟这些,它就违背了测试的目的。所以我的问题是,我需要 HttpSession 对象来返回我模拟的数据,并且对于其他情况,它的行为应该像任何正常的 HttpSession 对象一样。就像,如果代码执行 session.setAttribute("name","Vivek")
,那么 session.getAttribute("name")
之后应该返回“Vivek”,但是如果是模拟对象,它会返回“NULL”,为什么?因为我没有 mock “getAttribute(“name”) 的行为。
简单来说就是对 HttpSession 或接口(interface)的部分模拟。
最佳答案
HttpSession
是一个接口(interface),因此您需要编写自己的实现,或者模拟它。我建议用 Mockito 模拟它,然后 stub getAttribute
和setAttribute
委托(delegate)给HashMap
,或其他一些合适的结构。
因此,在您的测试类中,您将具有
的字段- 你被 mock 了
HttpSession
, - 真实的
HashMap<String,Object>
你将使用Answer<Object>
每个 getAttribute
的对象和setAttribute
。每个Answer
只会将调用委托(delegate)给 HashMap
。
您可以在 @Before
中设置所有这些方法,或在@Test
中像这样的方法。
@Mock private HttpSession mockHttpSession;
Map<String,Object> attributes = new HashMap<String,Object>();
@Test
public void theTestMethod() {
Mockito.doAnswer(new Answer<Object>(){
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
String key = (String) invocation.getArguments()[0];
return attributes.get(key);
}
}).when(mockHttpSession).getAttribute(anyString());
Mockito.doAnswer(new Answer<Object>(){
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
String key = (String) invocation.getArguments()[0];
Object value = invocation.getArguments()[1];
attributes.put(key, value);
return null;
}
}).when(mockHttpSession).setAttribute(anyString(), any());
关于java - 对 HttpSession 的部分模拟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22982360/