我有以下设置:
public String loadFile(String uri) throws ClientProtocolException, IOException {
StringBuilder resp = new StringBuilder();
HttpClient client = HttpClientBuilder.create().build();
HttpGet request = new HttpGet(uri);
HttpResponse response = client.execute(request);
}
,Testclass看起来像这样:
@RunWith(JMockit.class)
public class FakeLoaderTest {
FakeLoader loader = new FakeLoader(); //class under test
@Test
public void testLoadFile(
@Mocked @Cascading final HttpClientBuilder mockBuilder,
@Capturing final HttpClient mockClient
) throws IOException, URISyntaxException{
new Expectations() {{
HttpClientBuilder.create().build(); result = mockClient;
mockClient.execute(withAny(mockget)); result = new IOException("test - test");
}};
loader.loadFile();
}
}
这给了我" ClosableHttpClient.execute的意外调用 - 期望是HttpClient.execute"
HttpClientBuilder.create.build()返回一个ClosableHttpClient,它实现了HttpClient。我认为@Capturing负责模拟扩展所讨论的类/接口的所有类?
这正常,正如预期的那样:
@Mocked @Cascading final HttpClientBuilder mockBuilder,
@Capturing final **Closeable**HttpClient mockClient
但我想测试接口,因为我没有测试使用的HttpClient实现。 在这个测试中,我不在乎是否有人在apache决定ClosableHttpClient由" ThinHttpCLient"作为默认实现,只要apache坚持HttpClient接口,我就不想改变这个测试用例。它是关于测试IO异常的内部处理(例如,他是否登录到正确的位置?他是否正确地重试等)。
如何使用JMockit和JUnit处理此问题?
提前感谢,
BillDoor
答案 0 :(得分:1)
测试应如下:
@Test(expected = IOException.class)
public void loadFile(
@Cascading HttpClientBuilder mockBuilder,
@Mocked final CloseableHttpClient mockClient
) throws Exception
{
new NonStrictExpectations() {{
mockClient.execute((HttpGet) any); result = new IOException("test");
}};
loader.loadFile("uri");
}
HttpClientBuilder#build()
的返回类型是 CloseableHttpClient
,它是一个包含常见方法实现的抽象类。 Apache项目永远不会将此返回类型更改为其他类型,因为它会导致API更改,从而导致编译错误。
此外,@Capturing
在这种情况下不再执行@Mocked
,因为使用@Cascading HttpClientBuilder
意味着不会实例化实际的实现类。