java - 所有类的模拟 URL

标签 java unit-testing

我有一个类 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/

相关文章:

java - Android Studio - - MainActivity 中只有 1 个按钮播放声音

java - Spark/Java 应用程序的 Dockerfile 通过 Spark Operator 执行

android - Android 应用程序中的单元测试。我该怎么办?

ruby - 是否有调试 RSpec (RSpec2) 中顺序相关测试失败的好方法?

java - JMockit 在单元测试中保持不变

unit-testing - 在 Go 中测试依赖于动态 URL 的处理函数

java - JAVA中如何根据环境动态选择配置?

java - Java 是否适合 Multi-Tenancy SAAS 架构?

java - 奥利奥 : android. content.res.Resources$NotFoundException

php - PHPUnit 中两个 TestCase 类之间的依赖测试