【问题标题】:Test Failure Message in mockito : Argument(s) are different! Wanted:mockito 中的测试失败消息:参数不同!通缉:
【发布时间】:2014-08-09 00:00:10
【问题描述】:

我正在我的 JUnit 中测试一个 Restful 端点,并在 作为参数存在于 save 方法中的列表,

**"Argument(s) are different! Wanted:"** 
save(
"121",
[com.domain.PP@6809cf9d, 
com.domain.PP@5925d603]
);
Actual invocation has different arguments:
save(
"121",
[com.domain.PP@5b6e23fd,  
com.domain.PP@1791fe40]
 ); 

当我调试代码时,代码在下面的 verify 行中断并抛出 以上异常。看起来像保存中“testpPList”中的参数 方法不同。我不知道当我在我的 JUNit 正确,然后调用 RestFul URL。

请求您提供宝贵意见。谢谢。

代码:

@Test
public void testSelected() throws Exception {
    mockMvc.perform(put("/endpointURL")
        .contentType(TestUtil.APPLICATION_JSON_UTF8)
        .content(TestUtil.convertObjectToJsonBytes(testObject)))
        .andExpect(status().isOk());
    verify(programServiceMock, times(1)).save(id, testpPList);
    verifyNoMoreInteractions(programServiceMock);
}

控制器方法:

@RequestMapping(value = "/endpointURL", method = RequestMethod.PUT)
public @ResponseBody void uPP(@PathVariable String id, @RequestBody List<PPView> pPViews) {
    // Code to construct the list which is passed into the save method below
    save(id, pPList);
}

【问题讨论】:

    标签: junit mockito


    【解决方案1】:

    实现Object#equals(Object)可以通过相等比较来解决。尽管如此,有时您正在验证的对象无法更改或其equals 函数无法实现。对于这种情况,建议使用org.mockito.Matchers#refEq(T value, String... excludeFields)。所以你可以使用类似的东西:

    verify(programServiceMock, times(1)).save(id, refEq(testpPList));
    

    只需用refEq 包装参数即可解决问题。

    【讨论】:

    • 很棒的答案!为我工作。语法如下:verify(serviceName).methodCall(refEq(passedParameter));
    • 我试过了,但在我的情况下它说:java.lang.IllegalStateException: Mockito.refEq(transactionToAdd) must not be null
    • @iDemigod 似乎您的变量 transactionToAdd 为空,这就是它对您失败的原因。
    • @EliuX ,是的,但这是因为可空对象上的 Kotlin/Java 关系(通过 stackoverflow.com/a/50489612/3569545 解决)
    【解决方案2】:

    确保在com.domain.PP 中实现equals 方法。

    [编辑]

    这个结论的原因是你失败的测试消息表明它需要这个PP列表

    [com.domain.PP@6809cf9d, com.domain.PP@5925d603]
    

    但它正在获取这个 PP 列表

    [com.domain.PP@5b6e23fd, com.domain.PP@1791fe40]
    

    每个PP 对象的@ 符号后面的十六进制值是它们的哈希码。因为它们不同,则表明它们属于不同的对象。所以 equals 的默认实现会说它们不相等,这是 verify() 使用的。

    无论何时实现equals(),最好也实现hashCode():根据hashCode 的定义,两个相等的对象必须具有相等的hashCode。这确保了像 HashMap 这样的对象可以使用 hashCode 不等式作为对象不等式的快捷方式(这里,将具有不同 hashCode 的对象放在不同的桶中)。

    【讨论】:

    • 这是对问题的一个很好的解释。但这需要更改 java 代码才能成功运行 JUnit 测试。除了在 java 类中实现 equals 方法,还有其他优雅的解决方案吗?
    猜你喜欢
    • 2018-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-25
    相关资源
    最近更新 更多