Использование общего метода Mockito any ()

У меня есть интерфейс с методом, который ожидает массив Foo:

public interface IBar {
  void doStuff(Foo[] arr);
}

Я издеваюсь над этим интерфейсом, используя Mockito, и я хотел бы заявить, что вызывается doStuff(), но я не хочу проверять, какой аргумент передан - «все равно».

Как написать следующий код, используя общий метод any() вместо anyObject()?

IBar bar = mock(IBar.class);
...
verify(bar).doStuff((Foo[]) anyObject());

person ripper234    schedule 22.11.2009    source источник


Ответы (4)


Начиная с Java 8, вы можете использовать метод any без аргументов, а аргумент типа будет выведен компилятором:

verify(bar).doStuff(any());

Объяснение

Новым в Java 8 является то, что целевой тип выражения будет использоваться для определения параметров типа его подвыражений. До Java 8 для вывода параметров типа использовались только аргументы методов (большую часть времени).

В этом случае тип параметра doStuff будет целевым типом для any(), а тип возвращаемого значения any() будет выбран в соответствии с этим типом аргумента.

Этот механизм был добавлен в основном для возможности компиляции лямбда-выражений, но в целом он улучшает вывод типов.


Примитивные типы

К сожалению, это не работает с примитивными типами:

public interface IBar {
    void doPrimitiveStuff(int i);
}

verify(bar).doPrimitiveStuff(any()); // Compiles but throws NullPointerException
verify(bar).doPrimitiveStuff(anyInt()); // This is what you have to do instead

Проблема в том, что компилятор определит Integer как тип возвращаемого значения any(). Mockito не узнает об этом (из-за стирания типа) и вернет значение по умолчанию для ссылочных типов, равное null. Среда выполнения попытается распаковать возвращаемое значение, вызвав для него метод intValue перед передачей его в doStuff, и возникнет исключение.

person Lii    schedule 17.06.2015
comment
Я приятно удивляюсь каждый раз, когда за этот ответ набирают голоса! Я бы предположил, что этот вопрос не будет привлекать особого внимания со времен Java 8, поскольку метод any должен просто работать. Вы не ищите ответы на вопросы, которые просто работают! - person Lii; 12.05.2020
comment
Я пришел сюда, потому что не знал, почему мой код не работал с any(), но был в порядке с anyBoolean(), что прекрасно проливает свет в последней части вашего ответа. - person AdrienW; 22.06.2020

Это должно работать

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.verify;

verify(bar).DoStuff(any(Foo[].class));
person jitter    schedule 22.11.2009
comment
на всякий случай кому-то это понадобится в Scala: verify(bar).DoStuff(any[Array[Foo]]) - person tolitius; 30.05.2012
comment
У меня была проблема с импортом, я использовал any () из hamcrest в моем импорте, и он столкнулся с одним из mockito. - person Doppelganger; 13.06.2014
comment
Пожалуйста, ознакомьтесь с API, аргумент класса используется только для преобразования, метод по-прежнему принимает любые объекты! site.mockito.org / mockito / docs / current / org / mockito /. В этом случае используйте isA () site.mockito.org/mockito/docs/current/org/mockito/. - person thilko; 31.08.2015
comment
Этот класс объявлен устаревшим, чтобы избежать конфликта имен с Hamcrest. Используйте org.mockito.ArgumentMatchers - person leo9r; 23.03.2019

Для этого можно использовать Mockito.isA():

import static org.mockito.Matchers.isA;
import static org.mockito.Mockito.verify;

verify(bar).doStuff(isA(Foo[].class));

http://site.mockito.org/mockito/docs/current/org/mockito/Matchers.html#isA(java.lang.Class)

person thilko    schedule 31.08.2015
comment
Это правильный ответ. Совершенно неправильно использовать любой (Clazz). - person Surasin Tancharoen; 27.04.2017
comment
@SurasinTancharoen На самом деле any (Class) - это просто псевдоним isA (Class) (см. Документацию). Так что это совсем не так. - person jmiserez; 06.12.2017
comment
isA устарел - person Asiri Liyana Arachchi; 24.09.2020

Поскольку мне нужно было использовать эту функцию в моем последнем проекте (в какой-то момент мы обновили с 1.10.19), просто чтобы сохранить пользователей (которые уже используют mockito-core версии 2.1.0 или выше ), статические методы из приведенных выше ответов должны быть взяты из класса ArgumentMatchers:

import static org.mockito.ArgumentMatchers.isA;
import static org.mockito.ArgumentMatchers.any;

Имейте это в виду, если вы планируете обновлять свои артефакты Mockito, поскольку, возможно, начиная с версии 3, этот класс может больше не существовать:

Согласно версии 2.1.0 и выше, в документации Javadoc org.mockito.Matchers указано:

Используйте org.mockito.ArgumentMatchers. Этот класс объявлен устаревшим, чтобы избежать конфликта имен с классом Hamcrest * org.hamcrest.Matchers. Этот класс, скорее всего, будет удален в версии 3.0.

Я написал небольшую статью о подстановочных знаках mockito, если вы вверх для дальнейшего чтения.

person Maciej Kowalski    schedule 17.02.2017
comment
Как я могу импортировать org.mockito.ArgumentMatcher в Scala? Я пробовал импортировать org.mockito.ArgumentMatcher.any, я получаю ошибку `value any не является членом объекта org.mockito.ArgumentMatcher - person Manu Chadha; 08.03.2019
comment
Подскажите, пожалуйста, что эквивалентно в версии 3.0? - person Manu Chadha; 08.03.2019
comment
Узнаем, когда он выйдет;) - person Maciej Kowalski; 04.06.2019