2016-12-15 146 views
1

這裏使用Powermockito一個構造函數,給基類引用的是這種情況下,我有這樣的事情在我的一類方法MyClass的嘲諷在Java

public class MyClass{ 

    public Object build(Map map) { 

     BaseClass cls;  

     if(SomeconditionTrue) { 

     cls = new ChildClass1(new ABC()); 

     } else { 

     cls = new ChildClass2(new ABC()); 

     } 

     cls.callMethod(); 

    } 

} 

對於上述情形之一,我正在使用PowerMockito編寫測試用例,我想模擬此方法調用,cls.callMethod()。當我試圖嘲笑時,它會調用實際的方法callMethod(),這是失敗的。可以請一些身體幫我嘲笑那個方法嗎?嘗試使用PowerMockito PowerMockito.stub和其他一些選項的情景,但它總是調用實際的方法。嘲笑這種方法的原因是,它具有不同的邏輯,並且它調用了不同的API,方法相當複雜,因此我們需要嘲笑這種方法。

回答

1

你可以爲此轉向Powermock,但這並不一定是這種問題的「最佳」答案。

從本質上講,您在代碼中調用新的這一事實給您帶來了悲傷 - 您創建了難以測試的代碼。你可以看這些videos來理解我在說什麼。長話短說:不是轉向Powermock大錘子,而是反過來重做你的代碼;使用依賴注入。所以,不要自己創建這些對象,你的類可以使用一些工廠對象來提供它需要的對象。然後,您可以使用任何「普通」模擬框架(如EasyMock或Mockito)來創建該工廠的模擬版本。

編輯:我想你可能已經過度複雜的整個問題。你看,有一個基類或兩個子類並不重要。事情是:對於您的每種測試方法,您都應該準確理解將採用哪條路徑。您要麼想要創建child1或孩子。因此,我爲您建立一個簡化的解決方案:

package ghostcat.test; 

import org.junit.Test; 
import org.junit.runner.RunWith; 
import org.mockito.Mockito; 
import org.powermock.api.mockito.PowerMockito; 
import org.powermock.core.classloader.annotations.PrepareForTest; 
import org.powermock.modules.junit4.PowerMockRunner; 

class Abc {} 

abstract class Base { 
    void callMethod() { 
    System.out.println("Base::callMethod"); 
    } 
} 

class ChildClass1 extends Base { 
    ChildClass1(Abc abc) {} 
} 

class MyClass { 
    public Object build() { 
    System.out.println("build1"); 
    Base cls = new ChildClass1(new Abc()); 
    System.out.println("build2"); 
    cls.callMethod(); 
    System.out.println("build3"); 
    return null; 
    } 
} 

@RunWith(PowerMockRunner.class) 
@PrepareForTest(MyClass.class) 
public class MockNewTest { 
    @Test 
    public void test() throws Exception { 
    ChildClass1 mock = Mockito.mock(ChildClass1.class); 
PowerMockito.whenNew(ChildClass1.class).withArguments(Mockito.any(Abc.class)).thenReturn(mock); 
    new MyClass().build(); 
} 

}

打印:

build1 
build2 
build3 

所以你可以看到 - 沒有在基地被調用;只是因爲那個孩子的對象被「完全」嘲笑了。

整點是:您的在測代碼只需要一個某一類型的對象;而且您事先知道這是孩子1還是孩子2。因此,您只需爲該課程創建一個模擬;並使用PowerMockito按順序返回模擬你剛剛創建的。

備案:我和間諜玩了一段時間;但他們在這裏沒有幫助;而且它們也不是必需的!

+0

感謝您的回覆。是的,我們可以選擇一些工廠模式,但我寫的測試用例是針對遺留代碼的,我們不想觸摸現有的代碼。除了更改現有代碼之外,是否還有其他選擇? – user2334926

+0

@ user2334926我更新了我的答案;拉了一個**爲我工作的完整**例子。 – GhostCat