匿名の内部クラステストの注意事項

2160 ワード

目的の方法
public void foo(){
    transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
    boolean success = transactionTemplate.execute(new TransactionCallback() {
        @Override
        public Boolean doInTransaction(TransactionStatus status) {
            try {
                barService.bar();
                return true;
            } catch (ApiException e) {
                System.out.println("call bar failed");
                e.printStackTrace();
                status.setRollbackOnly();
            }
            return false;
        }
    });
    if(success){
        barService.doSomething();
    }else{
        barService.doSomethingElse();
    }
}

テストメソッド
@Test
public void test_foo_call_bar_failed(){
    Mockito.doThrow(new ApiException("100000","Test")).when(barService).bar(); //  bar 
 
    service.foo();
 
    Mockito.verify(barService).bar();
    Mockito.verify(barService).doSomethingElse(); //  doSomethingElse 
    Mockito.verify(barService,Mockito.times(0)).doSomething();
}

しかし、実際に上記のテスト例を実行するとエラーが発生します.
java.lang.NullPointerException
    at com.foobar.service.FooService.foo(FooService.java:68)

匿名の内部クラスでは、このような簡単な処理でテスト方法を修正することはできないようです.
@Test
public void test_foo_call_bar_failed(){
    when(transactionTemplate.execute(Mockito.any(TransactionCallback.class))).thenAnswer(new Answer(){
        @Override
        public Object answer(InvocationOnMock invocation) throws Throwable {
            Object[] args = invocation.getArguments();
            TransactionCallback arg = (TransactionCallback)args[0];
            return arg.doInTransaction(new SimpleTransactionStatus());
        }
    });
    Mockito.doThrow(new ApiException("100000","Test")).when(barService).bar();
 
    service.foo();
 
    Mockito.verify(barService).bar();
    Mockito.verify(barService).doSomethingElse();
    Mockito.verify(barService,Mockito.times(0)).doSomething();
}

この時テストに合格できます.
リファレンスドキュメントhttp://stackoverflow.com/ques...