2016-11-11 44 views
0

我正在使用Mockito/PowerMockito在Java中編寫單元測試,但在測試中,我正在處理這個測試,我無法擺脫此UnfinishedStubbingException。Powermockito/Java - 正在測試的間諜類以驗證私有方法調用

我試圖測試的方法是私有的,所以我使用WhiteBoxImpl來調用該方法。在我調用的方法內部,可能會對被測試的類中的另一個私有方法(稱爲pm2)進行調用。我想驗證pm2永遠不會被調用,所以我爲被測試的類做了一個間諜,並且驗證pm2從不()被調用。

到目前爲止,此測試總是拋出一個UnfinishedStubbingException,但我無法弄清Powermockito不喜歡的測試部分。我有另一個(工作)測試非常類似,除非我不需要驗證像pm2這樣的方法的行爲。所以在這個工作案例中,我不需要爲被測試的類創建一個間諜。我相信我的問題與間諜有某種關係,但我不知道如何在沒有它的情況下測試我想要測試的內容。

這就是我現在所擁有的:

@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的方法我測試:

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 
    } 
} 

當我運行這個測試,我得到一個UnfinishedStubbingException。在堆棧跟蹤頂部的一行是:

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

問題行是

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

你似乎並不有一個thenthenReturnthenThrow這裏。你總是需要使用when之一。

+0

我再次檢查了我的代碼,我抄錄了這行錯誤。它應該是「.thenReturn(recordMock)」,而不是「.loadRecord(recordMock)」。 –

相關問題