【问题标题】:Mockito when() doesn't differentiate between child classesMockito when() 不区分子类
【发布时间】:2015-11-24 22:14:13
【问题描述】:

我编写了一个使用 Mockito 1.9.5 的测试。我有一个HttpGet 和一个HttpPost 执行HttpClient,我正在测试以验证每个响应是否以输入流的形式返回预期结果。

问题是在使用 Mockito.when(mockedClient.execute(any(HttpPost.class))).thenReturn(postResponse)Mockito.when(mockedClient.execute(any(HttpGet.class))).thenReturn(getResponse),其中响应是不同的对象,mockedClient.execute() 总是返回 getResponse

我写的测试如下:

private InputStream       postContent;
private InputStream       getContent;
@Mock
private FilesHandler hand;
@Mock
private MockHttpClient    client;
private MockHttpEntity    postEntity;
private MockHttpEntity    getEntity;
private MockHttpResponse  postResponse;
private MockHttpResponse  getResponse;
private String imgQuery = "someQuery";
private ParametersHandler ph;
private FileHandlerImpl   fileHand;
private String            indexFolder = "src/test/resources/misc/";
private String            indexFile   = "index.csv";

@Before
public void setUp() {
    MockitoAnnotations.initMocks(this);
    try {
        postContent = new FileInputStream(indexFolder + "testContent.txt");
        postEntity = new MockHttpEntity(postContent);
        postResponse = new MockHttpResponse(postEntity, new BasicStatusLine(new ProtocolVersion("http", 1, 1), 200, "postReasonPhrase"));
        getContent = new FileInputStream(indexFolder + "testContent.txt");
        getEntity = new MockHttpEntity(getContent);
        getResponse = new MockHttpResponse(getEntity, new BasicStatusLine(new ProtocolVersion("http", 1, 1), 200, "getReasonPhrase"));
        ph = new ParametersHandler();
        fileHand = new FileHandlerImpl(client, ph, indexFolder, indexFile);
    } catch (Exception e) {
        failTest(e);
    }
}
@Test
public void getFileWhenEverythingJustWorks() {

    try {
        Mockito.when(client.execute(Mockito.any(HttpPost.class))).thenReturn(postResponse);
        Mockito.when(client.execute(Mockito.any(HttpGet.class))).thenReturn(getResponse);
        fileHand.getFile(hand, imgQuery, ph, "I");
        Mockito.verify(hand).rebuildIndex(Mockito.any(String.class), Mockito.any(Map.class), Mockito.any(Map.class), hand);
    } catch (IOException e) {
        failTest(e);
    }
}

正在测试的方法的简化版本如下。

public void getFile(FilesHandler fileHandlerFl, String query, ParametersHandler ph, String type) {

        JsonFactory factory = new JsonFactory();
        HttpPost post = preparePost(query, factory);
        CloseableHttpResponse response = client.execute(post);

    String uri = "https://someuri.com" + "/File";
        HttpGet get = new HttpGet(uri);
        setParameters(get);
        response.close();
        response = client.execute(get);
}

一如既往,感谢您提供的任何帮助。

【问题讨论】:

    标签: java mockito apache-httpcomponents


    【解决方案1】:

    尽管在 Mockito 1.x、any(HttpGet.class) matches any value and not just any HttpGet 中用英语阅读时会意味着什么。该参数仅用于保存 Java 8 之前的强制转换。

    来自Matchers.any(Class) documentation

    匹配任何对象,包括空值

    此方法不对给定参数进行类型检查,它只是为了避免在代码中进行强制转换。但是,这可能会在未来的主要版本中发生变化(可能会添加类型检查)。

    请改用 isA(HttpGet.class)isA(HttpPost.class),请参阅下面 Brice 关于 any(Class<?> clazz) 匹配器未来更改的评论。

    【讨论】:

    • 作为历史参考,anyanything 的简写别名,当时 API 正在强制转换,贡献者和/或提交者考虑将类作为参数传递给避免这种转换,而不改变这个 API 的语义。然而,这个变化最终改变了人们认为这个 API 正在做的事情。 这将在 mockito 2+ 中修复
    • @Brice 感谢您提供信息!在 SO 上更新此答案和其他一些答案。
    • 我知道这已经有好几年了,但我们最近遇到了类似的问题。另一个对我们有用的解决方案是链接thenReturn 调用,知道调用的顺序。例如,when (httpClient.execute(Mockito.any())).thenReturn(getResponse).thenReturn(putResponse); 我喜欢 isA 作为更好的解决方案,但我想我会添加我们发现效果也很好的解决方案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-05
    相关资源
    最近更新 更多