2014-07-09 3 views
0

다음 테스트를 실행하면 원래 객체가 반환되고 모의 객체가 반환되지 않으므로 실제 메소드 getLevelCriteriaForLevel (level)이 실행 중입니다 (디버거에서 관찰 됨). 왜 이렇게이다? 나는 이것이 이미 어제 일했고 나는 그곳에서 아무 것도 바꾸지 않았을 것이라고 확신한다. Mockito/PowerMock .... 그런 다음 호출되지 않습니다?

는 이미
@PrepareForTest({LevelCriteria.class, LevelGenerator.class}) 

을 시도하거나 내가 전에 그랬던 것처럼 MockitoJunitRunner을 사용하지만,이 역시 도움이되지 않습니다. 다음은 코드입니다 (generateConcreteLevel은 private 메소드입니다. 예상 된 예외는 모의에서이 데이터를 전달할 때만 throw됩니다. 그렇지 않으면 예외가 throw되지 않기 때문에 테스트가 실패합니다. 모의 객체하지만 실제 개체) : 그런데

public class LevelGenerator 
{ 
    public void createLevel(int level) 
    { 
     generateConcreteLevel(levelCriteria.getLevelCriteriaForLevel(level)); 
    } 

    private void generateConcreteLevel(LevelCriterion levelCriterion) 
    { 
     int entryGroupCount = levelCriterion.getEntryGroupCount(); 
     int exitGroupCount = levelCriterion.getExitGroupCount(); 
     int exitsWhileEntries = levelCriterion.getExitsWhileEntries(); 
     int maxGroupSize = levelCriterion.getMaxGroupSize(); 
     List<Question> questions = levelCriterion.getQuestions(); 
     int speed = levelCriterion.getSpeed(); 
     Range blueItemsCount = levelCriterion.getBlueItemsCount(); 
     Range brownItemsCount = levelCriterion.getBrownItemsCount(); 
     Range greenItemsCount = levelCriterion.getGreenItemsCount(); 
     Range redItemsCount = levelCriterion.getRedItemsCount(); 
     Range whiteItemsCount = levelCriterion.getWhiteItemsCount(); 
     Range timespanBetweenGroups = levelCriterion.getTimespanBetweenGroups(); 
     float fractionOfCarAmountToLeave = levelCriterion.getFractionOfCarAmountToLeave(); 
     float fractionOfMinimumItemsAmountInCarParkToStartExits = levelCriterion.getFractionOfMinimumItemsAmountInCarParkToStartExits(); 

     checkItemsFitInEntryGroups(entryGroupCount, maxGroupSize, blueItemsCount, brownItemsCount, greenItemsCount, redItemsCount, whiteItemsCount); 
    } 

    private void checkItemsFitInEntryGroups(int entryGroupCount, int maxGroupSize, Range... ranges) 
    { 
     int totalRangeCount = 0; 
     for (Range range : ranges) 
     { 
      totalRangeCount += range.getMaximum(); 
     } 

     if (totalRangeCount > entryGroupCount * maxGroupSize) 
     { 
      throw new UnsupportedOperationException("Error in level criterion: Not enough entry groups for Items."); 
     } 
    } 
} 

시험 ...

@RunWith(PowerMockRunner.class) 
public class LevelGeneratorTest 
{ 
    @Mock 
    private LevelCriteria levelCriteriaMock; 

    @InjectMocks 
    private LevelGenerator levelGenerator; 

    @Test(expected=UnsupportedOperationException.class) 
    public void tooLessPositionsInEntryGroups() 
    { 
     LevelCriterion levelCriterion = new LevelCriterion.LevelCriterionBuilder() 
           .withBlueItemsCount(new Range(10, 10)) 
           .withEntryGroupCount(3) 
           .withExitGroupCount(3) 
           .withMaxGroupSize(3) 
           .build(); 

     when(levelCriteriaMock.getLevelCriteriaForLevel(anyInt())).thenReturn(levelCriterion); 

     levelGenerator.createLevel(0); 
    } 
} 

: 메이븐 빌드 같은 오류가 발생하기 때문에 그것은, 이클립스 문제가 아니에요. 리팩토링 한 후에 PowerMockito의 Whitebox로 직접 private 메소드를 실행할 수 있다는 것을 알고 있습니다.하지만 질문은 왜, 언제 ... 여기에서 작동하지 않는지입니다.

답변

0

나는 틀린 것을 알아 냈다. 불행하게도 클래스를 단순화 한 이래로이 질문에서 실제 문제는 보이지 않습니다.

실제 실제 LevelGenerator 구현에 매개 변수화 된 생성자가 있습니다. 그것이 어제 더 이상 작동하지 않는 이유입니다. 분명히 표준 생성자를 사용하지 않을 때 Mockito와 모의 주입 문제가 있습니다.

결과 : when ...은 예상대로 작동합니다.

+0

이것은 실제 질문에 대한 답변이 아니라 실제 삶의 문제에 대한 해결책입니다. ;-) 어쨌든 내 대답이 당신을 도왔 으면 좋겠다. – Jmini

0

질문입니다 가정 :

나는 조롱 구현을 기대 왜 실제 방법 getLevelCriteriaForLevel (수준이) 실행?

만약 당신이 그것을 재현하면 모든 것이 잘 동작하는 것으로 보여 주려합니다. 간단한 예제입니다 (필요하다면 현재 작업 공간에서 전환하십시오).

나는 LevelCriterion.LevelCriterionBuilder()을 가지지 않으므로 LevelCriterion (빈 객체)을 인스턴스화하여 테스트를 간소화했습니다. 구현시 항상 UnsupportedOperationException이 반환되므로 관련성이 없습니다.

내 LevelGenerator는 다음과 같습니다. UnsupportedOperationException은 가능한 한 간단합니다. LevelGenerator # generateConcreteLevel (LevelCriterion).

는 다음과 같이 구현 경우

public class LevelGenerator 
{ 
    LevelCriteria levelCriteria; 

    public void createLevel(int level) 
    { 
     generateConcreteLevel(levelCriteria.getLevelCriteriaForLevel(level)); 
    } 

    private void generateConcreteLevel(LevelCriterion levelCriteriaForLevel) 
    { 
     throw new UnsupportedOperationException("xxx"); 
    } 
} 

시험은 LevelGeneratorTest의 상단에 @RunWith(MockitoJUnitRunner.class)를 사용하여, 녹색이다.

나는 @PrepareForTest 또는 PowerMockRunner을 사용하지 않았습니다. Mockito 버전 1.9.5가 있습니다.

은 다음과 같습니다 때문에, 나는 진짜 getLevelCriteriaForLevel(level) 구현을 사용하지 않은 것을 확신 :

public class LevelCriteria { 

    public LevelCriterion getLevelCriteriaForLevel(int level) { 
     throw new IllegalStateException("Unexpected call"); 
    } 
} 

실제 getLevelCriteriaForLevel (INT)이 시험이 빨간색 excuted 경우 ((자), IllegalStateException가 발생하기 때문에) .

시험은 아직 녹색입니다 ...

이 방법은 pure-Mockito (버전 1.9.5) 접근 방식에서 작동합니다. 다른 모든 모의 라이브러리 (PowerMock, EasyMock ...)를 제거해야합니다.

정적 호출 when(..).thenReturn(..)이 Mockito 인 것이 확실합니까?

는 시도 유무 : Mockito.when(..).thenReturn(..)

나는 그것이 도움이되기를 바랍니다.

추신 : 질문을 업데이트 한 것으로 나타났습니다. 제게 조금 불공평하지만, 제 대답을 다시 한번 업데이트하지는 않을 것입니다. when(..) 호출이 작동 중임을 설명하기 위해 구현 세부 사항이 generateConcreteLevel(..) 일 필요는 없습니다. 내 대답을 다시 읽으십시오. 별도의 작업 공간에서 사용해보십시오. 그러면 혼자 볼 수 있습니다.

PS-2 : 나는 이클립스도 사용하고 있습니다 ... 왜 문제가되어야합니까? 이클립스는 훌륭한 IDE이다.

+0

LevelCriterion의 데이터로 인해 generateConcreteLevel에서 예외가 발생합니다. 구현의 실제 LevelCriterion 객체가 전달 될 때 예외를 throw하지 않습니다. 그리고 그것이 문제입니다. 귀하의 예제는 항상 예외를 throw합니다. 그것은 항상 녹색이어서 분명합니다. – Bevor

+0

나는 generateConcreteLevel (LevelCriterion)에서 뭔가가 필요하고 나의 구현은 당신의 질문에서 말하는 것이 사실이 아니라는 것을 증명하기에 충분하다. (TDD 방식) : "실제 메소드 getLevelCriteriaForLevel (level)이 실행 중이다. (나는 디버거) "내 실제 구현에서는 getLevelCriteriaForLevel (level)이 IllegalStateException을 던집니다 (코드가 실행되면 Unit 테스트가 빨간색으로 표시됨). 내가 말했듯이 MockitoJUnitRunner를 사용하십시오. PowerMock, EasyMock에 종속성을 제거하면 ... 작동한다는 것을 알 수 있습니다. – Jmini

+0

질문이 업데이트되었습니다. 결과는 10> 9 => 예외가되어야하지만 원본 levelCriteria가 사용되며 모의 객체가 아니므로 예외를 throw하지 않는 실제 levelCriterion이 반환됩니다. – Bevor

관련 문제