这是我的问题:
这是我尝试编写测试用例的方法。
此方法尝试创建“HttpClient”实例,但此服务器在我这边不可用。
所以我试图通过使用模拟来实现这一点,但我没有成功。
那么有人可以告诉我该怎么做吗?
方法如下:
public boolean callGet(final boolean keepResult) {
boolean ok = false;
if (url != null) {
try {
log.appendLine("Url:");
log.append(url);
final HttpClient client = new HttpClient();
setAuthentication(client);
final GetMethod method = new GetMethod(url);
if (Utils.isFilled(userAgent)) {
method.setRequestHeader("User-Agent", userAgent);
}
status = client.executeMethod(method);
ok = (status == HttpStatus.SC_OK);
log.appendLine("Status http call:");
log.append(status);
if (ok) {
if (keepResult) {
if (maxSizeResult > 0) {
result = method
.getResponseBodyAsString(maxSizeResult);
} else {
result = method.getResponseBodyAsString();
}
}
}
} catch (final Exception e) {
}
}
return ok;
这是我的单元测试方法:
@Before
public void start() {
urlcaller = new UrlCaller();
UrlCaller mock1 = Mockito.mock(UrlCaller.class);
Mockito.when(mock1.callGet(true)).thenReturn(true);
}
@Test
public void testSetUserAgent() throws HttpException, IOException {
boolean t1 = urlcaller.callGet(true);
System.out.println(t1);
}
}
这是我收到的错误:
Problem:
UrlCaller.java
javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:946)
...
at de.bcode.utilsWithLog.UrlCaller.callGet(UrlCaller.java:115)
at de.bcode.utilsWithLog.TestUrlCaller.testSetUserAgent(TestUrlCaller.java:52)
Caused by:
java.io.EOFException: SSL peer shut down incorrectly
at sun.security.ssl.InputRecord.read(InputRecord.java:482)
...
at de.bcode.utilsWithLog.UrlCaller.callGet(UrlCaller.java:115)
at de.bcode.utilsWithLog.TestUrlCaller.testSetUserAgent(TestUrlCaller.java:52)
false
感谢您阅读所有问题:-)希望它足够清楚。
最佳答案
您当前的方法存在几个问题:
在单独测试另一个类时,您通常会使用模拟/ stub /假货/任何东西,即提供协作者类的假实现。 例如,您可以单独对某个 Controller 进行单元测试,并为其每个协作对象提供模拟(一个假存储库、一个假 UrlCaller,...)。这样您就可以单独测试被测系统(= Controller )的实际生产代码,而无需依赖其协作者的正确功能。
您的测试创建了 UrlCaller 类的真实和虚假对象,然后它继续执行真实的 urlcaller 对象。这意味着所有实际的生产代码都会被触发,并且创建的模拟 URL 调用者很高兴什么也不做。
在这些情况下我通常会做的是:
- 弄清楚 UrlCaller 类的单一职责
- 如果它有任何难以测试/外部的依赖关系(比如真正的 HTTP 流量),请将它们分离到一个新类中,并提供某种方法用假的替换这个协作对象(您可以通过使用构造函数注入(inject)或子类来做到这一点)例如,测试模式)
- 在生产代码中为您的协作者提供生产实现
- 在您的测试代码中提供一个虚假的实现来测试您的被测系统,而无需那些令人讨厌的外部依赖项。
对于您的具体情况:似乎使此代码难以测试的外部依赖项是 HttpClient。尝试从 UrlCaller 中提取对该类的依赖关系。如果这对您来说似乎是一个没有实际意义的问题(“但是 UrlCaller 类不会做任何事情”),我会放弃单独测试 UrlCaller 类的冲动,而只依赖于进行真正的 http 调用的集成测试.
关于unit-testing - 在这种情况下如何使用模拟?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29935136/