Saturday, December 10, 2011

JUNIT - java.lang.IllegalStateException: 2 matchers expected, 1 recorded.

So I've been planning to write this down for a long time, finally got sometime to do it.

If you are new to JUnit you would often find yourself facing this error .

java.lang.lllegalStateException: 2 matchers expected, 1 recorded
or
i matchers expected, j recorded.....

Here is the complete trace:

java.lang.IllegalStateException: 2 matchers expected, 1 recorded.
at
org.easymock. internal. Expected Invocation .create MissingMatchers( Expected Invocation .java :56)
at org.easymock. internal. Expected Invocation.<init>( Expected Invocation .java :48)
at org.easymock.internal.Expectedlnvocation.<init>(Expectedlnvocation.java:40)
at org.easymock.internai.RecordState.invoke(RecordState.java:76)
at org.easymock.internal.MocklnvocationHandler.invoke(MocklnvocationHandler.java:38)
at org.easymock.internal.ObjectMethodsFilter.invoke(ObjectMethodsFilter.java:72)
at $Proxy2 .getDataByGroupslist( Unknown Source)
at
..................................
at sun.reflect.NativeMethodAccessorlmpl.invokeO(Native Method)
at sun.reflect.NativeMethodAccessorlmpl.invoke(NativeMethodAccessorlmpl.java:4~)
at sun.reflect.DelegatingMethodAccessorlmpl.invoke(DelegatingMethodAccessorlmpl.java:25)
at java .lang. reflect. Method. invoke( Method .java :600)
at org.junit.runners.modei.FrameworkMethod$1.runReflectiveCaii(FrameworkMethod.java:44)
at org.j unit. intern a l.runners.modei.ReflectiveCa liable .run( ReflectiveCa II a ble.java: 15)
at org.j unit. runners. mode I. Fra mewo rkMethod. invoke Explosively( Framewo rkMethod .java :41)
at org.junit.internal.runners.statements.lnvokeMethod.evaluate(lnvokeMethod.java:20)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.runners.BiockJUnit4CiassRunner.runChild{BiockJUnit4CiassRunner.java:76)
at org.junit.runners.BiockJUnit4CiassRunner.runChild{BiockJUnit4CiassRunner.java:SO)
at org.junit.runners.ParentRunner$3.run{ParentRunner.java:193)
at org.junit. runners. Pa rentRunner$1.sched ule{Pa rentRu n ner.java :52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$OOO{ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.eclipse.jdt.interna l.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390}
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

How to fix this?

The answer is that "The mock should contain all fixed values or all matchers."
EasyMock documentation (http://easymock.org/EasyMock2_2_Documentation.html) says
"If you would like to use matchers in a call, you have to specify matchers for all arguments of the method call. ."

For Example 
1.  EasyMock.expect(testTableDao.getDataByGroupslist(groups, 1)).andReturn(testTablesRows);   - works
2.  EasyMock.expect(testTableDao.getDataByGroupslist(EasyMock.isA(List.class), EasyMock.isA(Integer.class))).andReturn(testTablesRows);   - works
3.  EasyMock.expect(profileDao.getProfilesByGroupslistAndCntctCntrCode(groups,EasyMock.isA(Integer.class))).andReturn(testTableRows); -doesn't work

The code1 perfectly works fine because both the parameters for the method of the mocked object are fixed values.
The code2 perfectly works fine because both the parameters for the method of the mocked object are matchers.
The code3 would throw the java.lang.lllegaiStateException: 2 matchers expected, 1 recorded  because one parameter is a fixed value and the other is a matcher.

Saturday, December 3, 2011

Ajax call using JQuery

Here is a basic version of the method that does ajax call using jquery. This does a synchronous ajax call. Change async parameter to true to make it asynchronous.

function doAjaxCall(url, dataMap){
    var jqxhr =$.ajax({ uri: uri,
    type: "POST",
    data: dataMap,
    cache: false,
    async: false
    })
    .success( function(){})
    .error(function() {})
    .complete(function() {});
    return jqxhr;
}




var data={};
data.inputOne = 1;
data.inputTwo = "test";
url= "testUrl.do" ;

jqxhr = doAjaxCall(url, data);
jqxhr.success(function(html){
 alert("return value is: " + html);
});

jqxhr.error(function(html){
 alert("error occured: " + html);
});

How to override hashCode() and equals() method of a java class



Here is a basic version

public class TestClass implements Serializable{

    private static final long serialVersionUID = -6529629340276202620L;
    private Integer accountId;
    private String accountName;
    public Integer getAccountId() {
        return accountId;
    }
    public void setAccountId(Integer accountId) {
        this.accountId = accountId;
    }
    public String getAccountName() {
        return accountName;
    }
    public void setAccountName(String accountName) {
        this.accountName = accountName;
    }


    @Override
    public int hashCode() {
        final int PRIME = 31;
        int result = 1;
        result= PRIME* result+ ((accountId ==null) ? 0 : accountId.hashCode());
        result= PRIME* result+ ((accountName ==null) ? 0 :    accountName.hashCode());
        return result;
    }
   
  @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
       
        if (obj == null)
            return false;
       
        if ( getClass () != obj.getClass () )
            return false;
       
        final TestClass other = (TestClass) obj;
       
        if (accountId == null){
            if (other.getAccountId() !=null)
                    return false;
            else if (!accountId.equals(other.getAccountId()))
                    return false;
        }
       
        if (accountName == null){
            if (other.getAccountName() !=null)
                    return false;
            else if (!accountName.equals(other.getAccountName()))
                    return false;
        }   
       
        return true;       
    }
   

Thursday, December 1, 2011

JUnit - Partial Mocking of an object under test


So I was trying to write unit tests for my methods using JUnit and EasyMock and the method I was writing unit test for is a method that calls another public method
of the same object under test. In the example below I am writing unit test for methodThatCallsMethodsOneAndTwo(). We don't want to get into the business logic
of other methods, we would just want to concentrate on the method under test.


With EasyMock we can mock some methods of the object under test .

testObject = EasyMock.createMockBuilder(DemoClass.class) .addMockedMethod("methodOne", Integer.class).addMockedMethod("methodTwo",
String.class) .createMock();



See the entire example.

public class DemoClass{

  public String methodOne(Integer demoInputOne){
     //calls some webservice or an ejb or some other object, gets data, processes it and returns a string.
   
     return "abc" ; // this is determined programatically
  }
 
  public List<Integer> methodTwo(String demoInputTwo){
     //Calls some dao, gets the data, does some logic and returns an arraylist
   
     return  demoList; // this is determined programatically
  }
 
  public Boolean methodThatCallsMethodsOneAndTwo(){
    String methodOneResult = methodOne(1);
    List<Integer> methodTwoResult = methodTwo(methodOneResult);
    //does some other logic and returns true or false
    return true;
   }   
}


   public class TestDemoClass{
    DemoClass testObject ;
   
    @Test   
    public void testMethodThatCallsMethodsOneAndTwo() {
        testObject = EasyMock.createMockBuilder(DemoClass.class) .addMockedMethod("methodOne", Integer.class).addMockedMethod("methodTwo",
String.class) .createMock();

   
    Integer demoInputOne = 1 ;   
    List<Integer> demoList = new ArrayList<Integer>();
    demoList.add(1);
    demoList.add(2);
    EasyMock.expect(testObject.methodOne(demoInputOne)) .andReturn("abc");
    EasyMock.expect(testObject.methodTwo("abc")) .andReturn(demoList);
    EasyMock.replay(testObject);
    Assert.assertTrue("This must be true",testObject.methodThatCallsMethodsOneAndTwo());
   
    }
}

Shown below is the old way of doing it in older versions of JUnit. However the methods used are now deprecated in latest versions of JUnit.


testObject = EasyMock.createMock(
DemoClass.class,DemoClass.class.getMethod("nethodOne", new
Class[] {Integer.class}),
DemoClass.class.getMethod("methodTwo",ne
w Class[] {String.class} )) ;


NO WE CAN'T MOCK A PRIVATE METHOD USING EASYMOCK.