我有这个类,我正在尝试模拟UrlWrapper.class的对象创建
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 :(得分:1)
您的问题在这里:
@PrepareForTest({UrlWrapper.class, WorkerClass.class
然后:
Runnable runnable = new Runnable() {
事情是:您不在工作人员类中调用 new 。您正在创建一个匿名内部类的Worker(即Runnable实例化) - 并且您正在进行 new 调用。
我看到两个选项:
我怀疑你是第一个工作的选择。即使这样可行,也可能是一些非常肮脏的解决方法。
真实答案是:了解如何编写可测试代码,例如通过观看这些videos。您的真正的问题是对 new 的调用。一个解决方案:创建一个工厂,为您提供URL对象;然后使用依赖注入来获取runnable中的工厂。
没有PowerMock(ito)就可以嘲笑那个工厂......突然间,你的整个设计得到了改进;同时,它变得更容易测试。