EasyMock Void方法对象哈希码的不匹配

时间:2013-04-12 10:58:31

标签: java junit mocking easymock

我为HttpSession创建了一个模拟对象,如下所示。

HttpSession mocks.createMock(HttpSession.class);

现在我正在测试方法的一些方法

public String validateProduct(String productId,Model model,HttpServletRequest request){
    Customer customer=new Customer();
    Product product=customerService.validateProduct(productId, VSCConstants.CLIENT_CODE);
    customer.setProduct(product);
    /*Doing more operation with customer*/
    request.getSession().setAttribute(
            VSCConstants.SESSION_CUSTOMER,customer);
    request.setAttribute("response", "InValidVIN");
    return "forward:/profile";
}

现在我的junit测试代码是

expect(customerService.validateProduct(null, VSCConstants.CLIENT_CODE))
            .andReturn(new Product());
expect(request.getSession()).andReturn(session).anyTimes();
    session.setAttribute(VSCConstants.SESSION_CUSTOMER, createdObject);
    expectLastCall().andAnswer(new IAnswer<Customer>() {
          public Customer answer() throws Throwable {
              createdObject= (Customer) EasyMock.getCurrentArguments()[1];
              return null;
          }
    });

现在的问题是session.setAttribute()方法是void方法,所以我使用过 expectLastCall()但是如果你看到我正在测试的方法是创建一个新客户并将其添加到会话中,那么这里就会出现不匹配问题,而且我正在流动异常。

Unexpected method call HttpSession.setAttribute("SESSION_CUSTOMER", com.budco.vsc.domain.Customer@feebefcb):
HttpSession.setAttribute("SESSION_CUSTOMER", null): expected: 1, actual: 0
at org.easymock.internal.MockInvocationHandler.invoke(MockInvocationHandler.java:44)
at org.easymock.internal.ObjectMethodsFilter.invoke(ObjectMethodsFilter.java:85)
at $Proxy6.setAttribute(Unknown Source)
at com.budco.vsc.mvc.controller.AdvancedCustomerSearchController.validateProduct(AdvancedCustomerSearchController.java:110)
at com.budco.vsc.mvc.controller.AdvancedCustomerSearchController.getAdvancedSearchResult(AdvancedCustomerSearchController.java:83)
at com.budco.vsc.mvc.controller.AdvancedCustomerSearchControllerTest.testgetAdvancedSearchResultWithValidateProduct(AdvancedCustomerSearchControllerTest.java:148)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)

显示在......

我希望,我需要使用在测试方法中使用的相同客户对象,但由于该方法正在创建对象,因此无法实现。 第二个选项可能会覆盖hashCode()但它会很重,因为该方法在客户身上做了很多事情,而且它是一个非常大的对象,其中包含许多其他对象和集合。  有没有简单的方法,所以我只是跳过不匹配。

2 个答案:

答案 0 :(得分:1)

我认为你几乎就在那里(见下文)。这里1是您尝试获取句柄的Customer对象的setAttribute中的参数索引。一旦拥有它,您应该能够毫无问题地比较两个Customer对象。

  private static Customer createdObject;


  expectLastCall().andAnswer(new IAnswer<Customer>() {
      public Customer answer() throws Throwable {
          createdObject = (Customer) EasyMock.getCurrentArguments()[1];
          return null;
      }
  });

答案 1 :(得分:1)

在测试servlet代码时,我个人会避免使用模拟框架模拟请求,响应和会话,而是使用专用的MockHttpServletRequestMockHttpServletResponseMockHttpSession对象,所有这些都是你可以通过编程方式与之互动。

您可以在this JarFinder Search for MockHttpSession中看到,几乎所有主要的Web框架都有这些类的版本。就个人而言,我更喜欢描述in the Spring Referencein the package javadoc

的Spring模拟组件