Search code examples
javajunitmockingeasymock

EasyMock Void Methods mismatch of object hashcode


I have create an mock object for HttpSession like below.

HttpSession mocks.createMock(HttpSession.class);

Now i am testing some method the method is

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";
}

Now my junit test code for that is

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;
          }
    });

Now the problem is as the session.setAttribute() method is void method so i have used expectLastCall() but if you see the method which I am testing is creating a new customer and adding that to the session so here it's getting mismatch and I am getting flowing exception.

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)

show on .....

I hope , I need to use the same customer object which is use inside the test method but it's not possible as the method is creating the object. Second option may be overriding the hashCode() but it will be heavy as the method doing lot of things on customer and it's a very big object contenting lot of other object and collections. Is there any easy way so that I simply skip the mismatch.


Solution

  • You're nearly there I think (see below). Here 1 is the parameter index in setAttribute for the Customer object you're trying to get a handle on. Once you have it you should be able to compare the two Customer objects without any problems.

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