部分模仿HttpSession

Viv*_*vek 2 java junit unit-testing mockito

有一个我想要测试的servlet,servlet有会话,并在会话中放入"loginBean"(其中包含登录的用户相关信息),我已经嘲笑并且工作正常,现在在GUI级别,有2个选项卡,DetailSet1, detailsS​​et2,当你输入DetailSet1的数据时,它会被保存在会话中并且也会做一些业务逻辑,现在它来到DetailsS​​et2,你已经在会话中有了DetailSet1,所以它得到了它所需要的一切,数据保存在DB中.现在很明显我必须模拟HttpSession,因为我从容器外部运行单元格,但是存储的数据也在HttpSession中,如果我也嘲笑它们,它就会破坏测试的目的.所以我的问题是,我需要HttpSession对象返回我模拟的模拟数据,并假设其他情况下的任何正常HttpSession对象.就像,如果代码确实如此session.setAttribute("name","Vivek"),那么之后session.getAttribute("name")应该返回"Vivek",但是在模拟对象的情况下它返回"NULL"为什么?因为我没有嘲笑"getAttribute("name")的行为.

简单来说,HttpSession或Interfaces的部分模拟.

Daw*_*ica 8

HttpSession是一个接口,所以你需要编写自己的实现,或者模拟它.我建议用Mockito嘲笑它,然后抄写getAttributesetAttribute委托给一个HashMap或其他合适的结构.

因此,在您的测试类中,您将拥有字段

  • 你的嘲笑HttpSession,
  • 一个真实的 HashMap<String,Object>

并且你将为Answer<Object>每个getAttribute和使用对象setAttribute.每个人Answer都会将呼叫委托给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());
Run Code Online (Sandbox Code Playgroud)