无法使用PowerMockito/Mockito模拟URL类 [英] Unable to mock URL class using PowerMockito/Mockito

查看:646
本文介绍了无法使用PowerMockito/Mockito模拟URL类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用PowerMockito在正在测试的代码中模拟java.net.URL类的创建.基本上,我想防止真正的HTTP请求发生,而是1)在发出请求时检查数据,以及2)在模拟响应上提供我自己的测试数据.这就是我正在尝试的:

I am trying to use PowerMockito to mock the creation of the java.net.URL class in my code that I'm testing. Basically, I want to prevent the real HTTP request from occurring and instead 1) check the data when the request is made and 2) supply my own test data back on a mocked response. This is what I'm trying:

@RunWith(PowerMockRunner.class)
@PrepareForTest({ URL.class, MockedHttpConnection.class })
public class Test {
    URL mockedURL = PowerMockito.mock(URL.class);
    MockedHttpConnection mockedConnection = PowerMockito.mock(MockedHttpConnection.class);

...
    PowerMockito.whenNew(URL.class).withParameterTypes(String.class).withArguments("MyURLString").thenReturn(mockedURL);
PowerMockito.when(mockedURL.openConnection()).thenReturn(mockedConnection);

...
}

我要测试的代码如下:

URL wlInvokeUrl = new URL(wlInvokeUrlString);
connection = (HttpURLConnection) wlInvokeUrl.openConnection();

在较早的测试场景中,我模拟了wlInvokeUrlString以匹配"MyURLString".我还尝试使用whenNew行的各种其他形式,尝试注入模拟.不管我尝试什么,它都不会拦截构造函数.我要做的就是捕获"对openConnection()的调用,并使它返回模拟的HTTP连接,而不是真实的HTTP连接.

Earlier in my test scenario I mock the wlInvokeUrlString to match "MyURLString". I've also tried using various other forms of the whenNew line, trying to inject the mock. No matter what I try, it never intercepts the constructor. All I want to do is "catch" the call to openConnection() and have it return my mocked HTTP connection instead of the real one.

在同一脚本中,我已经在此类之前嘲笑了其他类,这些类均按预期工作.我或者需要第二只眼睛(可能是真的),或者URL类有一些独特之处.我确实注意到,如果我使用"whenNew(URL.class).withAnyArguments()"并将"thenReturn"更改为"thenAnswer",则可以触发它.唯一的问题是我永远都不会收到代码的URL调用.我看到的是对URL.class的3参数构造函数的调用,其中所有参数都为null.此类可能来自Java运行时,并由测试运行程序引导吗?非常感谢您的帮助.

I have mocked other classes ahead of this one in the same script and these are working as expected. Either I need a second pair of eyes (probably true) or there is something unique about the URL class. I did notice that if I use "whenNew(URL.class).withAnyArguments()" and change the "thenReturn" to "thenAnswer" I could get it to trigger. Only problem is I never get the URL call for my code. What I see is an invocation of the 3-argument constructor for URL.class with all nulls for the parameters. Could it be this class is from the Java runtime and is bootstrapped by the test runner? Any help is much appreciated.

推荐答案

使用PowerMockito.whenNew时,这是一个常见错误.

It's a common mistake when use PowerMockito.whenNew.

请注意,您必须为创建MyClass的新实例(而不是MyClass本身)的类做准备.例如.如果执行new MyClass()的类称为X,则必须执行@PrepareForTest(X.class)才能使whenNew起作用

Note that you must prepare the class creating the new instance of MyClass for test, not the MyClass itself. E.g. if the class doing new MyClass() is called X then you'd have to do @PrepareForTest(X.class) in order for whenNew to work

来自 Powermock Wiki

因此,您需要稍作更改,然后将一个类添加到@PrepareForTest中,该类创建一个新的URL实例,例如:

So, you need a bit change your test and add to @PrepareForTesta class which create a new instance of URLlike:

@RunWith(PowerMockRunner.class)
@PrepareForTest({ URL.class, MockedHttpConnection.class , ConnectionUser.class})
public class URLTest {
public class URLTest {

    private ConnectionUser connectionUser;

    @Before
    public void setUp() throws Exception {

        connectionUser = new ConnectionUser();
    }

    @Test
    public void testName() throws Exception {

        URL mockedURL = PowerMockito.mock(URL.class);
        MockedHttpConnection mockedConnection = PowerMockito.mock(MockedHttpConnection.class);

        PowerMockito.whenNew(URL.class).withParameterTypes(String.class).withArguments("MyURLString").thenReturn(mockedURL);
        PowerMockito.when(mockedURL.openConnection()).thenReturn(mockedConnection);

        connectionUser.open();

        assertEquals(mockedConnection, connectionUser.getConnection());


    }
}

其中:

public class ConnectionUser {

    private String wlInvokeUrlString = "MyURLString";
    private HttpURLConnection connection;

    public void open() throws IOException {
        URL wlInvokeUrl = new URL(wlInvokeUrlString);
        connection = (HttpURLConnection) wlInvokeUrl.openConnection();
    }

    public HttpURLConnection getConnection() {
        return connection;
    }
}

这篇关于无法使用PowerMockito/Mockito模拟URL类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆