使用PowerMock模拟构造函数
發生這種情況時,您有三種選擇:
顯然,選項1并不是一個嚴肅的選項,盡管我建議重構以將所有內容移至依賴項注入,但這需要時間,而且您必須務實。 這就是PowerMock的用處。此博客演示了如何使用PowerMock模擬構造函數,這意味著當您的代碼調用new時,它不會創建真實的對象,而是會創建模擬對象。
為了證明這個想法,我們首先需要測試一些類,如下所示。
public class AnyOldClass {public String someMethod() {return "someMethod";}}public class UsesNewToInstantiateClass {public String createThing() {AnyOldClass myclass = new AnyOldClass();String returnValue = myclass.someMethod();return returnValue;}}第一個類AnyOldClass是代碼通過調用new實例化的類。 在這個例子中,顧名思義,它可以是任何東西。
第二個類,恰當地命名為UsesNewToInstantiateClass,具有一個方法createThing(),該方法在調用時會執行以下操作:
AnyOldClass myclass = new AnyOldClass();這一切都非常簡單,因此我們將快速進行PowerMock輔助的JUnit測試:
import static org.easymock.EasyMock.expect; import static org.junit.Assert.assertEquals; import static org.powermock.api.easymock.PowerMock.expectNew; import static org.powermock.api.easymock.PowerMock.replay; import static org.powermock.api.easymock.PowerMock.verify;import org.junit.Test; import org.junit.runner.RunWith; import org.powermock.api.easymock.annotation.Mock; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner;@RunWith(PowerMockRunner.class) @PrepareForTest(UsesNewToInstantiateClass.class) public class MockConstructorTest {@Mockprivate AnyOldClass anyClass;private UsesNewToInstantiateClass instance;@Testpublic final void testMockConstructor() throws Exception {instance = new UsesNewToInstantiateClass();expectNew(AnyOldClass.class).andReturn(anyClass);final String expected = "MY_OTHER_RESULT";expect(anyClass.someMethod()).andReturn(expected);replay(AnyOldClass.class, anyClass);String result = instance.createThing();verify(AnyOldClass.class, anyClass);assertEquals(expected, result);}}首先,該類具有通常的PowerMock附加功能:
@RunWith(PowerMockRunner.class) @PrepareForTest(UsesNewToInstantiateClass.class)在文件的頂部加上anyOldClass模擬對象的創建。 要考慮的重要代碼行是:
expectNew(AnyOldClass.class).andReturn(anyClass);這行代碼告訴PowerMock期望調用新的AnyOldClass()并返回我們的anyClass模擬對象。
同樣有趣的是重播和驗證的調用。 在上面的示例中,它們都有兩個參數。 第一個,AnyOldClass.class與上面的ExpectNew(…)調用有關,而第二個,anyClass則與簡單的模擬調用Expect(anyClass.someMethod())。Return(expected);相關。
在某些時候,您確實應該讓new來做它所做的事情:創建一個請求類型的新對象。 有一種觀點認為,在測試時您可能過度隔離代碼,而對所有內容進行模擬會降低測試的含義和價值。 對我來說,沒有正確的答案,這是一個選擇的問題。
很明顯,如果您的代碼訪問諸如數據庫之類的外部資源,那么您將重構并實現DI或使用PowerMock。 如果您的被測試代碼不訪問任何外部資源,那么更多的是判斷多少代碼隔離過多? 這也許需要一些思考,并且可能是另一天另一個博客的主題……
參考: 使用PowerMock從我們的JCG合作伙伴 Roger Hughes 嘲笑 “ Captain Debug's”博客中的 構造方法 。
翻譯自: https://www.javacodegeeks.com/2012/09/using-powermock-to-mock-constructors.html
總結
以上是生活随笔為你收集整理的使用PowerMock模拟构造函数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 通过beforeClass和afterC
- 下一篇: 花鱼怎么做才好吃 花鱼的烹饪方法