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

194

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

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

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

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

IBar bar = mock(IBar.class);
...
verify(bar).doStuff((Foo[]) anyObject());
ripper234
источник

Ответы:

111

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

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

объяснение

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

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

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


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

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

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, и возникнет исключение.

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

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

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

verify(bar).DoStuff(any(Foo[].class));
дрожание
источник
31
на всякий случай кому-то это нужно в Scala:verify(bar).DoStuff(any[Array[Foo]])
tolitius
6
У меня была проблема с импортом, я использовал any () из hamcrest в моем импорте, и он столкнулся с аналогичным из mockito.
Двойник
4
Пожалуйста, взгляните на API, аргумент класса просто используется для приведения, метод все еще принимает любой тип объекта! site.mockito.org/mockito/docs/current/org/mockito/… . Используйте isA () для этого случая site.mockito.org/mockito/docs/current/org/mockito/… .
thilko
1
Этот класс теперь не рекомендуется, чтобы избежать конфликта имен с Hamcrest. Используйте org.mockito.ArgumentMatchers
leo9r
12

Вы можете использовать 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)

thilko
источник
Это правильный ответ. Использовать любой (клац) совершенно неправильно.
Surasin Tancharoen
3
@SurasinTancharoen На самом деле, любой (класс) является просто псевдонимом isA (класс) (см. Документы). Так что это совсем не так.
Jmiserez
8

Поскольку мне нужно было использовать эту функцию для моего последнего проекта (в какой-то момент мы обновили с 1.10.19), просто чтобы пользователи (которые уже используют версию 2.1.0 mockito-core или выше ) были в курсе, статическая Методы из вышеупомянутых ответов должны быть взяты из 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.

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

Мацей Ковальский
источник
Как я могу импортировать org.mockito.ArgumentMatcher в Scala? Я попытался импортировать org.mockito.ArgumentMatcher.any Я получаю сообщение об ошибке `значение any не является членом объекта org.mockito.ArgumentMatcher
Manu
Не могли бы вы сказать мне, что является эквивалентом в версии 3.0?
Ману Чадха
Мы узнаем, как только он будет выпущен;)
Мацей Ковальский