Mockito проверяет вызовы методов

Я пытаюсь научиться использовать 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) будет вызываться один раз из-за поля "name" в String[]. Происходит то, что Mockito регистрирует record.setValue(строковый ключ, длинное значение) как то же самое, что и record.setValue(строковый ключ, строковое значение), что неверно. Строка 210 — это setValue в случае TIMESTAMP. Как я могу это исправить?


person David    schedule 14.05.2013    source источник
comment
Как вы создаете cursor? Я думаю, что было бы намного проще использовать настоящий объект record без насмешек и проверять правильность значений после их установки из курсора.   -  person denis.solonenko    schedule 14.05.2013
comment
Я издеваюсь над курсором. Я издеваюсь над всем, кроме тестируемого класса DataSource. Я все еще пытаюсь понять, над чем издеваться, а над чем нет   -  person David    schedule 14.05.2013


Ответы (1)


Если вы посмотрите на исходный код для InvocationMatcher, похоже, что логика проверки равенства методов немного шире, чем вы думаете, и в некоторых случаях может игнорировать перегрузку методов.

Я не уверен на 100%, но попробуйте заменить any(String.class) (который принимает любой объект из любой тип) с isA(String.class), который будет отфильтровывать вызовы, в которых этот параметр не является строкой. (anyString проверяет свой тип только в Mockito 2.0 и более поздних версиях.) Как ни странно, any(Foo.class) не означает «что угодно, если это Foo», это означает «что угодно». Это связано с изменениями в Mockito 2.0.

Конечно, вы также можете усилить проверку, чтобы она проверяла, что ключ или значение равны ожидаемому значению, но я не уверен, насколько это возможно в вашем случае.

person Jeff Bowman    schedule 15.05.2013