2011-11-17 79 views
2

可能重複:
Using Mockito to test abstract classes嘲諷抽象類

我有一個功能我需要測試一個抽象類。我可以創建該類的簡單衍生物,而不需要抽象方法的實現,但是可以使用嘲諷框架來完成嗎?我需要保持一流的內部狀態,所以我不能只是叫

mockedInstance = mock(ClassUnderTest.class); 

我需要的東西

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

但顯然這是不可能做到的是一個抽象類。

+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); 
    } 
} 

CNC中

  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

這種方法是要避免的,因爲你不再測試類,而是測試子類,並且可能掩蓋或引入錯誤。當測試被添加到測試夾具時,它也不能很好地擴展。 –