1

我正在尝试学习如何使用 Mockito,但我对如何验证某个对象上的方法被称为 X 次感到困惑。

我有以下测试代码

verify(record, times(1)).setValue(Mockito.any(String.class),Mockito.any(String.class));

以及我正在尝试测试的以下生产代码

我正在设置的字符串 [] 进行迭代

protected String[] columnNames = {"_id", "created_at", "updated_at", "name"};
protected ColumnType[] columnTypes = {ColumnType.INTEGER, ColumnType.TIMESTAMP, ColumnType.TIMESTAMP, ColumnType.TEXT};

以及循环中的生产代码,遍历 String[]

for (int i = 0; i < columnCount; i++) {

            if (columnNames[i].equals("_id")) {
                record.setId(cursor.getInt(0));
            } else {

                switch (columnTypes[i]) {
                    case BOOL:
                        record.setValue(columnNames[i], cursor.getInt(i));
                        break;
                    case TEXT:
                        record.setValue(columnNames[i], cursor.getString(i));
                        break;
                    case INTEGER:
                        record.setValue(columnNames[i], cursor.getInt(i));
                        break;
                    case TIMESTAMP:
                        record.setValue(columnNames[i], cursor.getLong(i));
                        break;
                    case LONG:
                        record.setValue(columnNames[i], cursor.getLong(i));
                        break;
                    case DOUBLE:
                        record.setValue(columnNames[i], cursor.getDouble(i));
                        break;
                    default:
                        record.setValue(columnNames[i], "");
                        break;
                }
            }
        }

这是我得到的错误

testDataSourceCanFindRecord(com.test.app.DataSourceTest) 经过时间:0.081 秒 <<< 失败!org.mockito.exceptions.verification.TooManyActualInvocations: customer.setValue(, ); 想要 1 次:-> 在 com.test.app.DataSourceTest.testDataSourceCanFindRecord(DataSourceTest.java:141) 但是是 3 次。不需要的调用:-> 在 com.test.core.DataSource.cursorToRecord(DataSource.java:210)

由于字符串 [] 中的“名称”字段,我期望 record.setValue(String key, String value) 被调用一次。发生的事情是 Mockito 将 record.setValue(String key, Long value) 注册为与 record.setValue(String key, String value) 相同的东西,这是不正确的。第 210 行是 TIMESTAMP 情况下的 setValue。我该如何纠正这个?

4

1 回答 1

0

如果您查看InvocationMatcher的源代码,检查方法相等性的逻辑似乎比您想象的要慷慨一些,并且在某些情况下可能会忽略方法重载。

我不是 100% 确定,但尝试用 替换any(String.class)(接受任何类型任何对象),这将过滤掉该参数不是字符串的调用。(仅在 Mockito 2.0 及更高版本中检查其类型。)违反直觉,并不意味着“只要它是 Foo”,它的意思是“任何东西”。这是由于 Mockito 2.0 的变化。isA(String.class)anyStringany(Foo.class)

当然,您也可以加强验证,以便检查键或值是否等于预期值,但我不确定在您的情况下这有多大可能。

于 2013-05-15T23:27:28.627 回答