2012-08-13 3 views
33

테스트 중에 주어진 모의와 어떤 상호 작용도 없었 음을 Mockito와 검증하는 방법을 찾고 있습니다. 확인 모드 never()을 사용하여 주어진 방법에 대해이를 달성하기는 쉽지만 아직 완전한 모의에 대한 해결책을 찾지 못했습니다.Mockito - 모의이 실행되지 않았 음을 확인하는 방법

실제로 달성하고 싶은 것은 테스트에서 콘솔에 아무것도 인쇄되지 않는다는 것을 확인하십시오. JUnit을 가진 일반적인 생각은 그렇게 간다 :

private PrintStream systemOut; 

@Before 
public void setUp() { 
    // spy on System.out 
    systemOut = spy(System.out); 
} 

@After 
public void tearDown() { 
    verify(systemOut, never()); // <-- that doesn't work, just shows the intention 
} 

PrintStream이 방법의 톤을 가지고 있으며, 정말 각을 확인하지 않으려는 확인 별개로 하나 하나 - ... 그리고 System.err에 대해 동일한

쉬운 해결책이 있다면, 나는 좋은 테스트 커버 리지를 가지고 있기 때문에 소프트웨어 엔지니어 (그리고 나 자신)가 System.out.println("Breakpoint#1");이나 e.printStacktrace(); 같은 디버그 코드를 제거하도록 강요하기를 바란다.

답변

37

사용이이 문제를 해결

import static org.mockito.Mockito.verifyZeroInteractions; 

// ... 

private PrintStream backup = System.out; 

@Before 
public void setUp() { 
    System.setOut(mock(PrintStream.class)); 
} 

@After 
public void tearDown() { 
    verifyZeroInteractions(System.out); 
    System.setOut(backup); 
} 
+0

나는이 접근법을 위해 할 수있는 최선처럼 보인다. 감사! (나는 실제로 도우미 클래스에서 대부분의 로직을 감추었으며 로거도 잠잠하게해야했다.) –

6
verifyZeroInteractions(systemOut); 

의견에서 언급했듯이 스파이에서는 작동하지 않습니다.

대체로 비슷한 답변이지만이 질문에 대한 답변을 참조하십시오.

+0

(facepalm) -하지만 스파이와 함께 작동하지 않는 것 같아요. 대신 PrintStream을 모의하고 시스템에 설정해야합니다 ... –

+0

코드를 보지 않고서는 이것이 왜 실패했는지 추측 할 수 있습니다. 간첩은 당신이 당신의 간첩을 그루터기로 만들 때, 그루터기에서의 메소드 호출은 실제로 검증 될 것으로 간주된다는 것입니다. 세 가지 제안. (1)'verifyNoMoreInvocations (ignoreStubs (mockOne, mockTwo));'이것은'verifyZeroInteractions'처럼 작동하지만 이미 스터브 한 것을 무시합니다. (2)'doReturn/doThrow/doAnswer' 메소드를 사용하여 스텁을 설정하고 있습니까? 이것들은 일반적으로 스파이를 다루는 데 있어서는 언제''~''다음/다음으로/다음 ''보다 더 잘 작동합니다. ... 계속 –

+0

제안 (3)은 여러분의 코드를 더 게시하여 여기 사람들이 여러분을 더 잘 도와 줄 수 있도록하는 것입니다. –

4

당신은 약간 다른 압정을 시도 할 수 있습니다 : 당신이 선호하는 경우

private PrintStream stdout; 

@Before public void before() { 
    stdout = System.out; 
    OutputStream out = new OutputStream() { 
     @Override public void write(int arg0) throws IOException { 
      throw new RuntimeException("Not allowed"); 
     } 
    }; 
    System.setOut(new PrintStream(out)); 
} 

@After public void after() { 
    System.setOut(stdout); 
} 

, 당신은 모의에 대한 익명의 유형을 전환 as Don Roby suggests을 확인할 수 있습니다.

+1

확실히 +1. 불행히도 이번에는 Mockito와 솔루션에 관심이 있었기 때문에 다른 대답을 받아 들일 것입니다. 희망은 당신이 상관 없어 :) –

2

한 가지 방법은 출력에 사용할 수있는의 PrintStream의 주입 수 있도록, 당신이 테스트하는 클래스를 리팩토링하는 것입니다. 이렇게하면 System 클래스의 동작에 의존하지 않고 단위 테스트를 수행 할 수 있습니다. 이 주입을 위해 패키지 전용 생성자를 사용할 수 있습니다. 왜냐하면 해당 테스트 클래스에서만 사용하기 때문입니다. 그래서 이런 식으로 보일지도 모릅니다.

public class MyClass{ 
    private PrintWriter systemOut; 

    public MyClass(){ 
     this(System.out); 
    } 

    MyClass(PrintWriter systemOut){ 
     this.systemOut = systemOut; 

     // ...any other initialisation processing that you need to do 
    } 
} 

클래스 자체 내에서 System.out 대신 system.ut 변수를 사용하십시오.

이제 테스트 클래스 내에서 모의 ​​객체 PrintStream을 만들고이를 패키지 전용 생성자에 전달하여 테스트 할 객체를 가져옵니다. 이제 테스트에서 원하는 모든 액션을 실행할 수 있으며 verify을 사용하여 모의에 미치는 영향을 확인할 수 있습니다 PrintStream.

+0

아, 괜찮지 만 의도하지 않은 것 : 나는 터치하지 않고 클래스를 테스트하는 방법을 찾으려고 노력했다. 특히 테스트에만 필요한 코드를 추가하지 않아도됩니다. 그러나 반면에, 우리가 테스트중인 클래스를 준비한다면, 이것은 정말 좋은 접근입니다! –

관련 문제