你可以爲此轉向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按順序返回即模擬你剛剛創建的。
備案:我和間諜玩了一段時間;但他們在這裏沒有幫助;而且它們也不是必需的!
感謝您的回覆。是的,我們可以選擇一些工廠模式,但我寫的測試用例是針對遺留代碼的,我們不想觸摸現有的代碼。除了更改現有代碼之外,是否還有其他選擇? – user2334926
@ user2334926我更新了我的答案;拉了一個**爲我工作的完整**例子。 – GhostCat