我有一个类 Record
,它使用 new URL(Record.SOURCE_URL)
。我有一个名为 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 类?
最佳答案
恕我直言,PowerMock 的使用是对不良设计的投降。它通常表明您未能遵循单一职责模式和关注点分离。例如:如果 URL 对象对于所有测试都是相同的,那么它很可能应该作为构造函数参数传递给被测代码 (CUT)...
此外,PowerMock 会更改您的 (CUT) 的字节码,这会导致测试覆盖工具无法工作。
同时为您的测试类设置继承树不是一个好主意。这是因为单元测试是 CUT 的文档,测试基类中的代码隐藏了一些关于 CUT 依赖项的重要信息。
所以有一些可能的解决方案。
最简单的方法是引入一个接缝,您可以在其中拦截 URL 的创建。为此,使用包私有(private)工厂方法封装 URL 实例化:
睾丸类:
URL createUrlFrom(String urlString){
URL url = // some code here
return url;
}
在您的测试类中,您可以使用普通 Mockito 创建 CUT 的 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);
}
关于java - 所有类的模拟 URL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42754195/