Jmockit - Mocked方法返回接口

时间:2014-09-16 09:33:38

标签: java junit jmockit

我有以下设置:

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

1 个答案:

答案 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意味着不会实例化实际的实现类。