JUnit Mockito URL and HttpsURLConnection



我有以下代码:

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

让我们仔细看看你的函数和你尝试测试的内容:

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 提取到一个单独的类。然后,在您的测试中根据您的需要模拟该流。但是不要对这种低级代码进行单元测试。

在我看来,您的预设置也是错误的。

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

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

//编辑: 在 Java 中模拟 URL

最新更新