2011-11-17 2 views
2

가능한 중복 :
Using Mockito to test abstract classes조롱 추상 클래스

는 내가 테스트해야하는 기능을 가진 추상 클래스가 있습니다. 나는 추상적 인 메소드를 구현하지 않고 그 클래스의 단순한 파생물을 만들 수있다. 그러나 조롱 프레임 워크로 할 수 있을까? 나는 클래스 내부 상태를 유지하기 위해 필요한, 그래서 난 그냥

mockedInstance = spy(new ClassUnderTest(...)); 

뭔가

필요

mockedInstance = mock(ClassUnderTest.class); 

호출 할 수 없습니다하지만 분명히이 클래스는 추상적이기 때문에 할 수 없다.

+3

[Mockito를 사용하여 추상 클래스를 테스트 할 수 있습니다] (http://stackoverflow.com/questions/1087339/using-mockito-to-test-abstract-classes). [이 답변] (http://stackoverflow.com/questions/1087339/using-mockito-to-test-abstract-classes/4317631#4317631)을 참조하십시오. – Yishai

답변

1
import org.junit.Test; 
import org.mockito.internal.stubbing.answers.CallsRealMethods; 

import static org.mockito.Mockito.*; 
import static org.junit.Assert.*; 

public class MockitoTest { 
    public static abstract class MyAbstractClass { 
     private int state; 
     public abstract int abstractMethod(); 
     public void method() { 
      System.out.println("method. State: " + (++state)); 
      System.out.println("abstractMethod: " + abstractMethod()); 
      anotherMethod(); 
     } 
     public void anotherMethod() { 
      System.out.println("anotherMethod. State: " + (++state)); 
     } 
    } 

    @Test 
    public void test() throws Exception { 
     MyAbstractClass obj = mock(MyAbstractClass.class, new CallsRealMethods()); 
     doReturn(5).when(obj).abstractMethod(); 

     obj.method(); 

     verify(obj).abstractMethod(); 

     assertEquals(2, obj.state); 
    } 
} 

-EDIT-

  1. 당신은 예를 들어 당신이 org.mockito.internal.util.reflection.Whitebox.setInternalState을 사용해야하는 객체의 내부 상태를 유지해야하는 경우 :

    @Test 
    public void test() throws Exception { 
        MyAbstractClass obj = mock(MyAbstractClass.class, new CallsRealMethods()); 
        setInternalState(obj, "state", 100); 
        doReturn(5).when(obj).abstractMethod(); 
    
        obj.method(); 
    
        verify(obj).abstractMethod(); 
        assertEquals(102, obj.state); 
    } 
    
  2. 당신이있는 경우를 생성자에 복잡한 논리를 가진 추상 클래스를 테스트하고 싶다면이 클래스를 확장해야합니다. 클래스를 테스트하거나 리팩터링하여 모든 로직을 테스트 할 메소드로 이동시킵니다.

+0

매개 변수를 생성자에 전달해야하는 경우 어떻게해야합니까? –

+0

답변이 업데이트되었습니다. – szhem

+0

내부 상태를 이렇게 설정하는 것이 약간 번거 롭습니다. 실제 예제에서는 훨씬 더 많은 변수, 복잡한 논리 등이있을 수 있습니다. –

2

내가 모의하지 않은 추상 클래스를 단위 테스트하고 싶을 때, 나는 하위 클래스입니다. 다른 대답 mijer에서

차입 코드는

public class MockitoTest { 
    public static abstract class MyAbstractClass { 
     private int state; 
     public abstract int abstractMethod(); 

     public int method(....) 
     { 
     ... 
     } 
    } 
} 


class Testclass extends MyAbstractClass 
{ 
     public int abstractMethod() 
     { 
     ... 
     } 
} 

다음의 TestClass의 인스턴스를 사용하여 MyAbstractClass의 테스트를 실행합니다. 로컬 서브 클래스에서 추상 메소드의 구현을 제어 할 수 있습니다.

+0

의도는 클래스를 확장하지 않고 조롱 프레임 워크를 사용하는 것입니다. –

+0

더 이상 클래스를 테스트하지 않고 하위 클래스이므로 마스크를 사용하거나 버그를 도입 할 수 있으므로이 방법을 피해야합니다. 또한 테스트가 테스트 픽스처에 추가되면서 확장이 잘되지 않습니다. –