2017-04-18 62 views
1

我正在嘗試爲預先存在的類寫一個測試。模擬內部最終對象

class ClassToBeTested { 

    private final Obj1 a; 

    ClassToBeTested(String anotherVariable) { 

    a = new Obj1(anotherVariable); 
    } 

public void methodToBeTested() { 

    if(invokeSomeOtherMethod()) { 
      a.getAnotherVariable().doSomething(); 
    } 
} 

public boolean invokeSomeOtherMethod() { 
     // return true or false based on some logic 
} 

Obj1 getObj1() { 
    return a; 
} 

} 

下面是我的測試類:

class TestClass { 


    @Test 
    public void testMethod() { 

     ClassToBeTested x = new ClassToBeTested("someString"); 
     ClassToBeTested spyX = spy(x); 
     doReturn(false).when(spyX).invokeSomeOtherMethod(); 

     spyX.methodToBeTested(); 
     verify(spyX, times(1)).getObj1().doSomething(); 

    } 
} 

這是我的理解: 由於OBJ1是在類的構造函數創建的私有最終目標,它既不在測試方法直接訪問也不會強制spyObject使用obj1的模擬版本。

此外,由於驗證()需要嘲笑OBJ1的版本,它會引發我一個錯誤: Wanted But Not invoked: x.getObj1(), however there are otherInteractions with this mock: x.invokeSomeOtherMethod()

我的理解是錯誤的?測試testMoethod()的方法是什麼?

+0

修改構造函數以便注入'a'? –

+0

我想避免這種情況,因爲它需要對項目中的多個文件進行更改。另外,a的初始化並不直接依賴於調用它的代碼,因爲'anotherVariable'只是一個當前未被使用的字符串。 – learningMyWayThru

+1

我不明白你的代碼。你的類只顯示一個構造函數 - 沒有參數的構造函數。但是你在測試方法中使用了一個沒有參數的構造函數。哪一個是對的? –

回答

1

你似乎不明白如何做適當的依賴注入。您不需要更改所有代碼以便於測試 - 只需使用構造器伸縮式示例即可:

class ClassToBeTested { 

    private final Obj1 a; 

    public ClassToBeTested(String anotherVariable) { 
    this(new Obj1(anotherVariable)); 
    } 

    ClassToBeTested(Obj1 a) { 
    this.a = a; 
    } 

完成。現在您有一個受封裝保護的構造函數,您可以使用它直接插入a的實例。所有其他生產代碼都可以保持原樣。

換句話說:不要通過使用嘲諷框架技巧「修復」您的設計問題。