Unit testing 在这种情况下如何使用模拟?
我的问题是: 这就是我试图编写测试用例的方法 此方法试图创建“HttpClient”的实例,但此服务器在我这边不可用 所以我试图通过模仿来实现这一点,但我没有成功 有人能告诉我怎么做吗 方法如下:Unit testing 在这种情况下如何使用模拟?,unit-testing,mocking,Unit Testing,Mocking,我的问题是: 这就是我试图编写测试用例的方法 此方法试图创建“HttpClient”的实例,但此服务器在我这边不可用 所以我试图通过模仿来实现这一点,但我没有成功 有人能告诉我怎么做吗 方法如下: public boolean callGet(final boolean keepResult) { boolean ok = false; if (url != null) { try {
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
感谢您阅读所有问题:-)希望问题足够清楚。您当前的方法有几个问题: 在隔离测试另一个类时,通常使用mock/stub/fakes/whatever,即提供协作者类的假实现。 例如,您可以单独对某个控制器进行单元测试,并为其每个协作对象(一个假存储库、一个假UrlCaller,…)提供模拟。这样,您就可以单独测试被测系统(=控制器)的实际生产代码,而无需依赖其协作者的正确功能 您正在讨论的测试创建了UrlCaller类的真实对象和虚假对象,然后继续执行真实的UrlCaller对象。这意味着所有实际的生产代码都会被触发,而创建的模拟url调用者很高兴什么也不做 在这些情况下,我通常做的是:
- 找出UrlCaller类的单一职责
- 如果它有任何难以测试的/外部依赖项(如真实的HTTP流量),请将这些依赖项分离到一个新类中,并提供某种方法用伪对象替换此协作对象(例如,您可以使用构造函数注入或子类来测试模式)
- 在生产代码中为合作者提供生产实现
- 在测试代码中提供一个伪实现,以便在没有这些讨厌的外部依赖的情况下测试被测系统
对于您的具体情况:似乎使代码难以测试的外部依赖是HttpClient。尝试从UrlCaller中提取该类的依赖项。如果这对您来说似乎是一个没有实际意义的观点(“但是UrlCaller类不会做任何事情”),我会放弃孤立地对UrlCaller类进行单元测试的冲动,只依赖于进行真正http调用的集成测试。您的测试没有多大意义。您创建一个mock并在测试中调用该mock 通常你是这样做的:
- 创建一个模拟(最好是一个接口)
- 将模拟注入被测单元
- 给你的测试单元打电话
我认为您应该将要模拟的部分与要测试的代码分开,并通过接口注入模拟的部分。您要测试哪些代码?