먼저 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를 테스트한 글이 나옵니다.
http://toby.epril.com/?p=195
저는 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()로 해결했습니다.