在HttpSession上部分模拟 [英] Partial Mocking on HttpSession
问题描述
有一个我要测试的servlet,servlet进行了会话,并将"loginBean"(包含已登录的用户相关信息)放入会话中,我已经对其进行了模拟并且可以正常工作,现在在GUI级别上,有2个选项卡,DetailSet1,detailsSet2,当您输入DetailSet1的数据时,它会保存在会话中,并且还会执行一些业务逻辑,现在是DetailsSet2,您已经在会话中有了DetailSet1,因此它获取了所有需要的数据,并将数据保存在DB中.现在很明显,我必须模拟HttpSession,因为我是从容器外部运行单元箱,但是要存储的数据也存储在HttpSession中,如果我也模拟了它们,那么就无法达到测试的目的.所以我的问题是,我需要HttpSession对象来返回模拟数据,以模拟所要模拟的数据,并且在其他情况下,它应该像任何普通的HttpSession对象一样工作.像,如果代码执行session.setAttribute("name","Vivek")
,则session.getAttribute("name")
之后应该返回"Vivek",但是如果是模拟对象,为什么返回"NULL"呢?因为我还没有嘲笑"getAttribute("name")"的行为.
There is a servlet i want to test , servlet have session and puts "loginBean" (which contain logged in user related info) inside session , which i have mocked already and working fine , now IN GUI level , there are 2 tab , DetailSet1 , detailsSet2 , when u enter data of DetailSet1 , it get saved in session and also does some business logic , now it comes to DetailsSet2 , you already have DetailSet1 in session , so it got all it needs , data is saved in DB. Now it's obvious i have to mock HttpSession because i am running unit cases from outside the container , but data which gets stored is also in HttpSession , if i mock those as well , it defeats the purpose of testing. so my Question is , i need HttpSession object to return mocked data for what i have it mocked for and it is suppose to act like any normal HttpSession object for other cases. Like , if code does session.setAttribute("name","Vivek")
, then session.getAttribute("name")
should return "Vivek" after that , but in case of mocked object it return "NULL" why? because i haven't mocked behaviour for "getAttribute("name").
简单来说就是HttpSession或接口的部分模拟.
In simple word Partial mocking for HttpSession or Interfaces.
推荐答案
HttpSession
是一个接口,因此您需要编写自己的实现或模拟它.我建议使用Mockito模拟它,然后将getAttribute
和setAttribute
存根以委派给HashMap
或其他合适的结构.
HttpSession
is an interface, so you'll need to either write your own implementation of it, or mock it. I would recommend mocking it with Mockito, then stubbing getAttribute
and setAttribute
to delegate to a HashMap
, or some other suitable structure.
因此,在您的测试课程中,您将拥有
So in your test class, you'll have fields for
- 您嘲笑的
HttpSession
- 真实的
HashMap<String,Object>
- your mocked
HttpSession
, - a real
HashMap<String,Object>
,您将对getAttribute
和setAttribute
的每个对象使用Answer<Object>
对象.每个Answer
都只会将呼叫委托给HashMap
.
and you'll use Answer<Object>
objects for each of getAttribute
and setAttribute
. Each Answer
will just delegate the call off to the HashMap
.
您可以使用@Before
方法或像这样的@Test
方法进行所有设置.
You could set all this up either in a @Before
method, or in a @Test
method like this.
@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());
这篇关于在HttpSession上部分模拟的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!