2017-06-21 31 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)的情况下进行模拟......突然之间,您的整个设计得到改进;同时它变得更容易测试。