2017-06-21 110 views
1

我有這個類,在這裏我想嘲笑對象創建的UrlWrapper.class懲戒新的()在Runnable的使用powerMockito

public class WorkerClass { 
    private final String url; 

    public WorkerClass(String url) { 
    this.url = url; 
    } 

    void performOperation(Executor executor) throws IOException { 
    Runnable runnable = new Runnable() { 
     @Override 
     public void run() { 
      UrlWrapper urlWrapper = null; 
      try { 
       urlWrapper = new UrlWrapper(url); 
       HttpURLConnection connection = (HttpURLConnection) urlWrapper.openConnection(); 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 

     } 
    }; 
    executor.execute(runnable); 
    } 
} 

這是測試代碼,我試過

@RunWith(PowerMockRunner.class) 
@PrepareForTest({UrlWrapper.class, WorkerClass.class}) 
public class TestClass { 
    @Before 
    public void init() throws Exception { 
    UrlWrapper urlWrapper = Mockito.mock(UrlWrapper.class); 
    PowerMockito.whenNew(UrlWrapper.class) 
       .withArguments(Mockito.anyString()) 
       .thenReturn(urlWrapper); 
    } 

    @Test 
    public void test() throws IOException { 
    Executor executor = new Executor() { 
     @Override 
     public void execute(Runnable command) { 
      command.run(); 
     } 
    }; 

    WorkerClass workerClass = new WorkerClass(""); 
    workerClass.performOperation(executor); 
    } 
} 

但它沒有被嘲笑。模擬工作正常,沒有Runnable。

我在這裏錯過了什麼?

+0

有趣的問題;我爲此投了票。雖然我的回答告訴你做一些完全不同的事情。我希望,你會發現答案至少upvote值得,現在你達到了這個水平;-) – GhostCat

回答

1

你的問題是這裏

@PrepareForTest({UrlWrapper.class, WorkerClass.class 

還有:

Runnable runnable = new Runnable() { 

事情是:你是不是調用工人內。您正在創建一個匿名工人內部類(即Runnable實例化) - 並且您正在執行新的調用。

我看到兩個選項:

  • 當然,匿名內部類......其實有一個類名。所以,也許您可以使用「錯位」的類名,並傳遞到@PrepareForTest
  • 避免調用這樣

我相當懷疑,你得到的第一個選項工作。即使這樣做,它可能會是一些非常骯髒的解決方法。

真正的答案是:學習如何通過觀看這些videos可測試代碼,例如。你的問題是打電話給新的。一種解決方案:創建一個工廠,爲您提供URL對象;然後使用依賴注入來獲取可運行的工廠。

該工廠可以在沒有PowerMock(ito)的情況下進行模擬......突然之間,您的整個設計得到改進;同時它變得更容易測試。