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

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

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

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

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

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

Ответ 1

Начиная с 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, и doStuff исключение.

Ответ 2

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

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

verify(bar).DoStuff(any(Foo[].class));

Ответ 4

Поскольку мне нужно было использовать эту функцию для моего последнего проекта (когда-то мы обновили с 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.

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