【发布时间】:2016-02-19 18:12:52
【问题描述】:
我正在尝试使用 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 连接,而不是真实的。
我已经在同一个脚本中模拟了这个类之前的其他类,这些类都按预期工作。要么我需要第二双眼睛(可能是真的),要么 URL 类有一些独特之处。我确实注意到,如果我使用“whenNew(URL.class).withAnyArguments()”并将“thenReturn”更改为“thenAnswer”,我可以触发它。唯一的问题是我从来没有收到我的代码的 URL 调用。我看到的是对 URL.class 的 3 参数构造函数的调用,其中所有参数都为空。难道这个类来自 Java 运行时并由测试运行程序引导?非常感谢任何帮助。
【问题讨论】:
-
你不需要 Powermock 来测试这个。只需模拟字符串 url,例如使用基于文件的路径(“file://my-test.properties”)。这会起作用,你可以传递你需要的数据
-
@JérémieB 你能详细说明一下吗?这似乎是一个优雅而简单的解决方案,但被测代码需要一个 HttpURLConnection,如果我更改 URL 字符串以引用文件(即 java.lang.ClassCastException: sun.net.www.protocol. ftp.FtpURLConnection 不能转换为 java.net.HttpURLConnection)。另外,您将如何使用这种方法验证请求中的输入参数?
-
你不应该直接使用
HttpURLConnection,而是URL和URLConnection。HttpURLConnection没有什么有用的。 URL 的目的是抽象传输层。
标签: junit mocking mockito powermock powermockito