Використання загального методу «будь-якого ()» Mockito


194

У мене є інтерфейс із методом, який очікує масив Foo:

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

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

Як мені написати наступний код, використовуючи any(), загальний метод, замість anyObject()?

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

Відповіді:


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, і виняток буде кинуто.


Я приємно здивований кожен раз, коли ця відповідь отримує відгук! Я б здогадався, що питання не приверне уваги з часу 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
про всяк випадок, коли комусь це знадобиться в Скалі:verify(bar).DoStuff(any[Array[Foo]])
tolitius

6
У мене виникли проблеми з імпортом, я використовував будь-який () від hamcrest в моєму імпорті, і він зіткнувся з одним із mockito.
Doppelganger

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)


Це правильна відповідь. Використовувати будь-який (Клац) абсолютно неправильно.
Surasin Tancharoen

3
@SurasinTancharoen Власне, будь-який (Class) є лише псевдонімом isA (Class) (див. Документи). Тож це зовсім не так.
jmiserez

8

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

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

Будь ласка, майте це на увазі, якщо ви плануєте оновлювати артефакти Mockito як можливо, починаючи з версії 3, цей клас може більше не існувати:

Відповідно до версії 2.1.0 і вище, Javadoc of org.mockito.Matchers зазначає:

Використовуйте org.mockito.ArgumentMatchers. Цей клас тепер застарілий, щоб уникнути зіткнення імені з класом Hamcrest * org.hamcrest.Matchers . Цей клас, ймовірно, буде видалено у версії 3.0.

Я написав невеличку статтю про макетні підказки, якщо ви готові до подальшого читання.


Як я можу імпортувати org.mockito.ArgumentMatcher у Scala? Я спробував імпортувати org.mockito.ArgumentMatcher.any, я отримую помилку `значення будь-хто не є об'єктом org.mockito.ArgumentMatcher
Ману Чадха

Скажіть, будь ласка, що таке еквівалент у версії 3.0?
Ману Чадха

Ми дізнаємось, як тільки буде випущено;)
Мацей Ковальський
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.