【问题标题】:Mockito verifying method callsMockito 验证方法调用
【发布时间】:2013-05-14 04:10:06
【问题描述】:

我正在尝试学习如何使用 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 秒 在 com.test.app.DataSourceTest.testDataSourceCanFindRecord(DataSourceTest.java:141) 但是是3次。不受欢迎的调用: -> 在 com.test.core.DataSource.cursorToRecord(DataSource.java:210)

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

【问题讨论】:

  • 如何创建cursor?我认为使用真正的record 对象而不进行模拟会容易得多,并在从光标设置它们后验证值是否正确。
  • 我在嘲笑光标。我正在嘲笑除正在测试的 DataSource 类之外的所有内容。我仍在试图弄清楚什么可以模拟,什么不可以

标签: android mockito robolectric roboguice


【解决方案1】:

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

我不能 100% 确定,但请尝试用 isA(String.class) 替换 any(String.class)(接受 any typeany object),这将过滤掉该参数不是字符串的调用。 (anyString 仅在 Mockito 2.0 及更高版本中检查其类型。)与直觉相反,any(Foo.class) 并不意味着“只要它是 Foo”,它的意思是“任何东西”。 This is due to change in Mockito 2.0.

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-02
    • 1970-01-01
    • 2014-03-21
    • 1970-01-01
    相关资源
    最近更新 更多