当前位置: 首页 > 知识库问答 >
问题:

无法使用PowerMockito/Mockito模拟URL类

姜钊
2023-03-14

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

@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连接。

我已经嘲弄了其他类前面的一个在同一脚本和这些工作的预期。要么我需要第二双眼睛(可能是真的),要么URL类有一些独特的东西。我确实注意到,如果我使用“WhenNew(url.class).WithanyArguments()”并将“ThenReturn”更改为“ThenAnswer”,我可以使它触发。唯一的问题是我从来没有得到我的代码的URL调用。我看到的是对url.class的三参数构造函数的调用,参数全部为空。会不会是这个类来自Java运行时,并且是由测试运行程序引导的?非常感谢任何帮助。

共有2个答案

步嘉德
2023-03-14

我不确定.WithParameterTypes(x).WithArguments(x)之间的区别,但我认为您需要按照如下方式设置它,以便代码工作。试试看,如果这没有帮助就告诉我。

PowerMockito.when(mockedURL.openConnection()).thenReturn(mockedConnection);
PowerMockito.whenNew(URL.class).withArguments(Mockito.anyString()).thenReturn(mockedURL);
戈安翔
2023-03-14

这是使用PowerMockito.WhenNew时常见错误。

请注意,您必须准备创建MyClass的新实例以进行测试的类,而不是MyClass本身。例如。如果执行new MyClass()的类名为X,那么您必须执行@PrepareForTest(X.class),以便whenNew工作

来自Powermock wiki

因此,您需要稍微更改测试,并向@PrepareForTest添加一个类,该类创建URL的新实例,如下所示:

@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为URL类创建一个模拟,并为其定义一些行为。代码如下: 抛出以下异常堆栈。特别是,这个测试的linke 39,这是我的位置:PowerMockito.when(mockURL.openConnection()). thenBack(mockConn);抛出错

  • 有人能帮帮我吗?提前谢了。

  • 我目前正试图模拟类中的私有final static对象。我的目标似乎没有被恰当地模仿。 示例: 代码:在主类中 嘲笑:在我的测试课上,我有 但是obj不返回我在执行时指定的值 并将实际运行。 任何建议都将是有帮助的,我也不能改变Main类中的任何代码,谢谢。

  • 使用mockito模拟一个方法会确保永远不会调用被模拟的方法吗?我有一个主类,它包含一些我想为其编写单元测试的代码,还有一个单元测试类MainTest,它包含主类的单元测试。 eg: 源类: JUnit测试(使用mockito) 这项测试失败了。为什么?

  • 我有以下测试代码: