【问题标题】:JUnit Mockito URL and HttpsURLConnectionJUnit Mockito URL 和 HttpsURLConnection
【发布时间】:2019-09-11 09:21:38
【问题描述】:

我有以下代码:

public byte[] myFunction(String s1, String s2, String s3) {

    try {           
            URL myUrl = new URL("https://myUrl");
            HttpsURLConnection connection = (HttpsURLConnection) myUrl.openConnection();
            connection.connect();

            int responseCode = connection.getResponseCode();
            String lastPacket = connection.getHeaderField("LastPacket");

            byte fileContent[] = IOUtils.toByteArray((InputStream) connection.getInputStream());
            return fileContent;
        }
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    }
}

我想对上面的代码进行单元测试。 所以我使用 MockitoJUnitRunner 编写了 JUnit:

@RunWith(MockitoJUnitRunner.class)
public class EvmlSeviceImplTest {

    @Mock
    private URL url;

    @Mock
    private HttpsURLConnection httpsURLConnection;

    @InjectMocks
    private MyClass myClass;

    @Before
    public void preSetup() {
        try {
            Mockito.doReturn(httpsURLConnection).when(url).openConnection();
            Mockito.doReturn(200).when(httpsURLConnection).getResponseCode();
            Mockito.doReturn("-1").when(httpsURLConnection).getHeaderField("LastPacket");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Test
    public void testMyFunction() {
        myClass.myFunction("my", "dummy", "data");
    }
}

但这里的问题是 URL 是最终类,而 Mockito 无法监视最终类。既然我们使用的是 MockitoJUnitRunner,那该怎么做呢?

我遇到了异常:

org.mockito.exceptions.base.MockitoException:无法模拟/监视类 java.net.URL

【问题讨论】:

  • 像你mock其他的一样mock最后一堂课,有什么问题,具体解释一下。
  • 我已经模拟了最终类的 URL,如上面的代码所示。我遇到了异常:Cannot mock/spy class java.net.URL
  • 您使用的是 Mockito 2.0 ??对吗??
  • @VishwaRatna 是的

标签: java junit mockito


【解决方案1】:

在我看来,您的 preSetup 也是错误的。

即使您模拟了 HttpsURLConnection (httpsURLConnection) 和 URL (url),这也不会在测试中使用。 您不能在测试或设置中只使用“url”(模拟的 URL),因为在您要测试的方法 (myFunction) 中,会创建一个新的 URL (myUrl)。这个“myUrl”和你嘲笑的“url”不一样。

我会将 URLConnection 作为参数传递给该方法(或创建第二个函数)。然后你就可以完全控制它并且可以模拟它。

// 编辑: Mocking a URL in Java

【讨论】:

    【解决方案2】:

    让我们仔细看看您的功能以及您尝试测试的内容:

    URL myUrl = new URL("https://myUrl"); // (1)
    HttpsURLConnection connection = (HttpsURLConnection) myUrl.openConnection(); // (2)
    connection.connect(); // (3)
    
    int responseCode = connection.getResponseCode(); // (4)
    String lastPacket = connection.getHeaderField("LastPacket");
    
    byte fileContent[] = IOUtils.toByteArray((InputStream) connection.getInputStream()); // (5)
    
    return fileContent;
    

    所以在第 1、2 和 3 行中,您创建了一个到某个远程资源的连接对象并连接到它。为此,您可以使用 SDK 的类。

    然后您检查响应代码 (4) 并从流中读取 (5)。同样,您为此使用了 SDK 的标准库。

    问题是:您是否真的想要对我们可以安全假设工作的代码进行单元测试?

    我要做的是将 1 到 4 的行提取到一个单独的类中,该方法返回一个您可以读取的流。然后,在您的测试中根据您的需要模拟该流。但是不要对这种低级代码进行单元测试。

    【讨论】:

      猜你喜欢
      • 2020-07-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多