2016-11-11 36 views
0

私はMockito/PowerMockitoを使ってJavaで単体テストを書いていますが、私が取り組んでいるテストでは、このUnfinishedStubbingExceptionを取り除くことはできません。Powermockito/Java - プライベートメソッド呼び出しを確認するためのテスト中スパイするクラス

私がテストしようとしているメソッドはプライベートなので、私はメソッドを呼び出すためにWhiteBoxImplを使います。私が呼び出したメソッドの中で、呼び出しがテスト対象のクラスの別のプライベートメソッド(pm2と呼ばれる)に行われる可能性があります。 pm2が呼び出されないことを確認したいので、テスト対象のクラスのスパイを作成し、pm2がnever()が呼び出されたことを確認します。

これまでのところ、このテストではUnfinishedStubbingExceptionがスローされていましたが、私のテストでPowermockitoが嫌いな部分はわかりません。私はpm2のようなメソッドの動作を検証する必要がないことを除いて、非常によく動作する別の(動作する)テストを持っています。だから、この実例では、テスト対象のクラスのスパイを作成する必要はありません。私は自分の問題が何とかスパイに関係していると信じていますが、私がそれを使わずにテストしようとしていることをテストする方法はわかりません。ここで

は、私が今持っているものだ:私はUnfinishedStubbingExceptionを取得し、このテストを実行すると

private BO BO = new BO(); 
private DAOI DAO = new DAO(); 

private void process(Message msg) { 
    try { 
     DAO.doAction(new Param1.class, msg.getId()); 
    } catch(Exception e) { 
     logger.error("some message"); 
     return; 
    } 

    Record record = null; 

    try { 

     int intParam1 = msg.getId(); 
     int intParam2 = msg.getDifferentId(); 

     MetaData metaData = BO.getMetaData(intParam1, intParam2); 

     record = DAO.loadRecord(new Param1(), msg.getId()); 

     // checkDelay is a private method in ServiceImpl.java 
     long delayForMinutes = checkDelay(record, msg, metaData); 
     if(delayForMinutes > 0) { 
      // Control should reach here 
      logger.debug("some message"); 
      return; 
     } 

     // Control should not reach here 

     if(Record != null && Record.getStatus() != CREATED) { 
      logger.debug("some message"); 
      return; 
     } 

     // Perform various actions 

    } catch(Exception e) { 
     // Perform other various actions 
    } 
} 

@Mock(name = "BO") 
BO BOMock; 
@Mock(name = "DAO") 
DAOI DAOMock; 

@InjectMocks 
ServiceImpl service; 

@Test 
public void unitTest(){ 
    MessageObject msg = new MessageObject(); 
    Record recordMock = mock(Record.class); 
    MetaData metaDataMock = mock(MetaData.class); 

    doNothing().when(DAOMock).doAction(any(Param1.class), anyInt()); 
    when(DAOMock.doOtherAction(any(Param1.class), eq(msg.getId()))).thenReturn(recordMock); 
    when(BOMock.getMetaData(anyInt(), anyInt()).thenReturn(metaDataMock); 

    ServiceImpl spy = PowerMockito.spy(this.service); 
    PowerMockito.doReturn(new Long(10)).when(spy, "checkDelay", recordMock, msg, metaDataMock); 

    Whitebox.invokeMethod(spy, "process", msg); 
    verify(recordMock, never()).getStatus(); 
} 

ここで私がテストだクラスServiceImplのメソッドです。スタックトレースの上部にある行は次のようになります。

DAO.doAction(new Param1.class, msg.getId()); 

エラーメッセージは、次のヒントを提供します。

E.g. thenReturn() may be missing. 
Examples of correct stubbing: 
    when(mock.isOk()).thenReturn(true); 
    when(mock.isOk()).thenThrow(exception); 
    doThrow(exception).when(mock).someVoidMethod(); 
Hints: 
1. missing thenReturn() 
2. you are trying to stub a final method, you naughty developer! 
3: you are stubbing the behaviour of another mock inside before 'thenReturn' instruction if completed 

をしかし、私はそれらのいずれかが私の状況に適用する方法を見つけ出すように見えることはできません。誰もがこのエラーを引き起こすために舞台裏で起こっていることを知っていますか?

あなたは

+1

UnitTestsは実装の詳細をテストすべきではありません。したがって、クラスに非公開メソッドがあるかどうかをテストする必要はありません。 DAOのインスタンスをサービスクラスに注入し、テスト用のモックを試してください(PowerMockを使用していません...) –

答えて

0

問題ラインはあなたがthenthenReturnまたはthenThrowここに持っていないようです

when(DAOMock.doOtherAction(any(Param1.class), eq(msg.getId()))).loadRecord(recordMock); 

ですありがとうございました。あなたはいつもwhenのものを使う必要があります。

+0

私は自分のコードを二重チェックしました。これは、 ".loadRecord(recordMock)"ではなく、 ".thenReturn(recordMock)"でなければなりません。 –

関連する問題