簡體   English   中英

Mockito和Powermock無法模擬ClassLoader

[英]Mockito and Powermock cannot mock ClassLoader

我在Java中有以下指令:

 String path = MyClass.class.getClassLoader().getResource(fileName).getPath();

我需要使用Mockito和Powermock模擬MyClass.class.getClassLoader()返回的ClassLoader

我嘗試了這個:

@Mock ClassLoader classLoader;

whenNew(ClassLoader.class).withAnyArguments().thenReturn(classLoader);

但這是行不通的。

有人知道怎么做嗎?

如注釋所示:您正在錯誤的級別上進行此操作。

查看您的代碼:

String path = MyClass.class.getClassLoader().getResource(fileName).getPath();

您會看到MyClass.class.getClassLoader().getResource(fileName)部分; 這是“內置”技術。

我的意思是:除非代碼的其他部分與ClassLoader混為一談,否則上述內容完全可以實現預期的功能。 絕對沒有必要對此進行廣泛的測試。 您只關心:這里的類和文件名; 東西給我一條路。 對你很重要。 因此: 抽象那個!

換句話說:您只需繼續添加其他抽象,例如:

public interface PathProvider {
   public Path getPathFromUrl(Class<?> clazz);
}

一個簡單的實現可能看起來像

public class PathProviderImpl implements PathProvider {
   @Override
   Path getPathFromUrl(Class<?> clazz, String fileName) {
     return clazz.getClassLoader().getResource(fileName).getPath();
}

或類似的東西。 請注意:您也可以編寫一個簡單的單元測試來檢查此實現。

但是核心要點是:您可以使用該接口的(模擬的)實例,而不是在生產代碼中進行靜態調用。

不需要PowerMock,不需要靜態模擬; 很好,簡單的模仿東西!

此外:以上解決了您的設計問題。 您創建了難以測試的生產代碼; 而且您不能通過使用PowerMock大錘來解決該問題; 您修復它可以改善不良設計。

您在嘲笑一個新的語句,但是您的代碼中沒有任何新的語句

據我了解,您應該:

  • 模擬靜態MyClass
  • 模擬getClassLoader()
  • 為ClassLoader創建一個模擬
  • 模擬方法getResource

如下所示:

@Mock ClassLoader classLoader;

    PowerMockito.mockStatic(MyClass.class);
    BDDMockito.given(MyClass.getClassLoader()).willReturn(classLoader);
    PowerMockito.doReturn("desiredResource").when(classLoader).getResource(Mockito.anyString());

另外,您可能需要在測試類的開頭設置以下幾行:

@RunWith(PowerMockRunner.class)
@PowerMockListener(AnnotationEnabler.class)
@PrepareForTest({MyClass.class})
public class yourTestClass....

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM