먼저 Criteria가 필요한데.. 애매합니다. 하이버네이트 Session이 만들어주는 객체인지라… 흠.. 난 Criateria나 Session을 테스트하고 싶은 생각은 없고 CriateriaUtils이 제대로 동작하는지만 확인하면 되는데 말이죠.

public class CriteriaUtils {
    public static void addOptionalLike(Criteria c, String fieldName, String value) {
        if(StringUtils.isEmpty(value)){
            c.add(Restrictions.ilike(fieldName, value, MatchMode.ANYWHERE));
        }    
    }
    public static void addOptionalEqual(Criteria c, String fieldName, Integer value) {
        if(value != null && value != 0){
            c.add(Restrictions.eq(fieldName, value));
        }
    }
}
이런코드가 있으니.. 조건이 잘 먹는지 제가 원하느대로 조건문을 쓴게 맞는지 확인하고 싶었습니다. 이럴때 사용할 수 있는게 목킹 프레임워죠. EasyMock이나 JMock, Mockito 등이 있는데 저는 Mockito가 편해서 이걸 쓰기로 했습니다.
검색해보니 EasyMock을 사용해서 Criteria를 사용하는 DAO를 테스트한 글이 나옵니다.
저는 EasyMock대신 Mockito를 사용했고, DAO 대신 CriteriaUtils를 테스트했습니다.
public class CriteriaUtilsTest {
    @Test
    public void testAddOptionalLike() throws Exception {
        Criteria c = mock(Criteria.class);
        CriteriaUtils.addOptionalLike(c, “name”, “whiteship”);
        verify(c).add(any(Criterion.class));
        reset(c);
        CriteriaUtils.addOptionalLike(c, “name”, null);
        verify(c, times(0)).add(any(Criterion.class));
        reset(c);
        CriteriaUtils.addOptionalLike(c, “name”, “”);
        verify(c, times(0)).add(any(Criterion.class));
        reset(c);
        CriteriaUtils.addOptionalLike(c, “name”, ”   “);
        verify(c, times(0)).add(any(Criterion.class));
    }
    @Test
    public void testAddOptionalEqual() throws Exception {
        Criteria c = mock(Criteria.class);
        CriteriaUtils.addOptionalEqual(c, “age”, 1);
        verify(c).add(any(Criterion.class));
        reset(c);
        CriteriaUtils.addOptionalEqual(c, “age”, null);
        verify(c, times(0)).add(any(Criterion.class));
        reset(c);
        CriteriaUtils.addOptionalEqual(c, “age”, 0);
        verify(c, times(0)).add(any(Criterion.class));
    }
}
웃긴건,… any(Criterion.class) 대신에 구체적인 예상 값이 add(Restrictions.ilke(“name”, “whiteship”, MatchMode.ANYWHERE))를 사용하면 결과가… 좀.. @_@
        Criteria c = mock(Criteria.class);
        CriteriaUtils.addOptionalLike(c, “name”, “whiteship”);
        verify(c).add(Restrictions.ilike(“name”, “whiteship”, MatchMode.ANYWHERE));
즉 이렇게 작성하면
Argument(s) are different! Wanted:
criteria.add(name ilike %whiteship%);
-> at osaf.util.CriteriaUtilsTest.testAddOptionalLike(CriteriaUtilsTest.java:25)
Actual invocation has different arguments:
criteria.add(name ilike %whiteship%);
-> at osaf.util.CriteriaUtils.addOptionalLike(CriteriaUtils.java:16)
Expected :criteria.add(name ilike %whiteship%);
Actual   :criteria.add(name ilike %whiteship%);
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at osaf.util.CriteriaUtilsTest.testAddOptionalLike(CriteriaUtilsTest.java:25)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:76)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:94)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:165)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:60)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:110)
이런 에러가 나는데.. 도무지 콘솔을 봐도 모르겠습니다. 콘솔에 찍힌게 같은데.. 다르다니?? 먼소리람.. 어차피 내가 원하건 Criateria에 add()가 호출되는냐 마느냐 였으니까 그냥 any()로 해결했습니다.