2016-11-11 1 views
0

Mockito/PowerMockito를 사용하여 Java에서 단위 테스트를 작성하고 있지만 현재 진행중인 테스트에서이 UnfinishedStubbingException을 제거 할 수 없습니다.Powermockito/Java - 전용 메서드 호출을 확인하기 위해 테스트중인 스파이 클래스

테스트하려는 메서드는 private이므로 메서드를 호출하기 위해 WhiteBoxImpl을 사용합니다. 필자가 호출 한 메소드 내에서 테스트중인 클래스에서 호출이 잠재적으로 다른 개인 메소드 (pm2라고 함)에 작성됩니다. 나는 pm2가 호출되지 않는다는 것을 확인하기를 원한다. 그래서 나는 테스트중인 클래스에 대해 스파이를 만들고, pm2가 never()가 호출되는지 확인한다.

지금까지이 테스트에서 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

문제 라인은 당신은 then, thenReturn 또는 thenThrow 여기없는 것 같습니다

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

감사합니다. 당신은 항상 when와 그 중 하나를 사용해야합니다.

+0

코드를 두 번 확인 했으므로 해당 행을 잘못 기록했습니다. ".loadRecord (recordMock)"가 아닌 ".thenReturn (recordMock)"이어야합니다. –

관련 문제