我有一个使用new URL(Record.SOURCE_URL)
的类Record
。我有一个称为BaseTestController
的测试基类。每个其他测试类都扩展了这一点。我想模拟new URL
,因为Record.SOURCE_URL
将无法在本地计算机上使用。
这就是我所拥有的:
@RunWith(PowerMockRunner.class)
@PrepareForTest(Record.class)
public abstract class BaseTestController {
@Before
public void setUp() {
PowerMockito.whenNew(URL.class).withArguments(Record.SOURCE_URL).thenReturn(PowerMockito.mock(URL.class));
}
}
这返回错误:
java.lang.abstractmethoderror:java.net.urlstreamhandler.openconnection(ljava/net/url;)ljava/net/urlConnection;
我如何正确模拟我的URL类?
IMHO使用 powermock 是对不良设计的投降。通常表明您未能遵循关注点的单一责任模式和分离。例如:如果对所有测试的URL对象都相同
也 powermock 更改您(剪切)的字节代码,从而导致测试覆盖工具无法正常工作。
也为您的测试课带有继承树是一个坏主意。这是因为剪切的Unitests是文档,测试基类中的代码隐藏了有关削减依赖项的一些重要信息。
所以有一些可能的解决方案。
最简单的是介绍 seam 您可以在其中拦截URL的创建。为此
testesclass:
URL createUrlFrom(String urlString){
URL url = // some code here
return url;
}
在您的测试课中,您可以使用普通的Mockito创建剪切的Spy :
@Spy
private CUT cut;
@Before
public static void setup(){
doReturn(myUrlMock).when(cut).createUrlFrom(anyString());
}
@Test
public static void createSpyAndMoclUrl(){
// do call on cut
verify(cut).createUrlFrom(THE_EXPECTED_URL_STRING);
}
在评论中不容易格式化代码,因此我将在此处发布建议(如果不起作用,则将其删除)
URL urlMock = PowerMockito.mock(URL.class);
HttpURLConnection huc = PowerMockito.mock(HttpURLConnection.class);
PowerMockito.when(urlMock.openConnection()).thenReturn(huc);
PowerMockito.whenNew(URL.class).withArguments(Record.SOURCE_URL).thenReturn(urlMock);