Як використовувати ArgumentCaptor для заглушки?


161

У документації Mockito та javadocs про це йдеться

Рекомендується використовувати ArgumentCaptor з верифікацією, але не з заглушкою.

але я не розумію, як ArgumentCaptor можна використовувати для заглушки. Чи може хтось пояснити вищезазначене твердження та показати, як ArgumentCaptor можна використовувати для заглушки або надати посилання, яке показує, як це можна зробити?


1
Супер короткий і добре пояснення: dzone.com/articles / ...
Benj

Відповіді:


271

Якщо припустити тестування наступного методу:

public boolean doSomething(SomeClass arg);

Mockito документація говорить , що ви повинні НЕ використовувати загарбник таким чином:

when(someObject.doSomething(argumentCaptor.capture())).thenReturn(true);
assertThat(argumentCaptor.getValue(), equalTo(expected));

Тому що ви можете просто використовувати матчер під час заглушки:

when(someObject.doSomething(eq(expected))).thenReturn(true);

Але перевірка - це інша історія. Якщо ваш тест повинен забезпечити, щоб цей метод був викликаний певним аргументом, використовуйте ArgumentCaptorцей випадок, для якого він призначений:

ArgumentCaptor<SomeClass> argumentCaptor = ArgumentCaptor.forClass(SomeClass.class);
verify(someObject).doSomething(argumentCaptor.capture());
assertThat(argumentCaptor.getValue(), equalTo(expected));

Дякую за відповідь. У мене є питання. У третьому кодовому блоці ми знаємо, що true повертається лише тоді, коли очікується, що він передається doSomething. Але коли істина повертається у другому блоці коду? Або хтосьObject завжди повертає true для деякогоMethod у такому випадку?
Не можу сказати

Гм, я вважаю, ви мали на увазі "Але коли в третьому блоці коду повертається істина ?". У третьому кодовому блоці ми просто не піклуємося про значення повернення, і нехай це буде одне за замовчуванням. Для булевих це так false, ні true.
Рорік

Ні, я рахував усі блоки сірого фону як блоки коду. Включаючи перший один вкладиш. Я мав на увазі рядок, коли (someObject.doSomething (argumentCaptor.capture ())). ThenReturn (true);
Не можу сказати

Ах, вибачте. Так, у цьому випадку true повернеться завжди.
Рорік

3
не впевнений, що причина "не використовувати з заглушкою" є простою причиною. Матчери не дають нам фактично очікуваного аргументу (лише тип), і це призводить до нормального тестування тестів, незважаючи на аргументи, які можуть бути помилковими.
dtc

0

Лінія

when(someObject.doSomething(argumentCaptor.capture())).thenReturn(true);

зробив би те саме, що

when(someObject.doSomething(Matchers.any())).thenReturn(true);

Отже, використовуючи argumentCaptor.capture (), коли заглушка не має додаткової вартості. Використання Matchers.any () краще показує, що насправді відбувається, і для цього краще для читабельності. З argumentCaptor.capture () ви не можете прочитати, які аргументи насправді відповідають. І замість того, щоб використовувати будь-який (), ви можете використовувати більш конкретні відповідники, коли маєте більше інформації (клас очікуваного аргументу), щоб покращити свій тест.

І ще одна проблема: Якщо при аргументі використовувати argumentCaptor.capture (), стає незрозумілим, скільки значень слід очікувати, щоб вони були захоплені після перевірки. Ми хочемо зафіксувати значення під час перевірки, а не під час заглушки, оскільки на даний момент ще немає значення для захоплення. Отже, що таке захоплення аргументу захоплення методом захоплення під час заглушки? чи він нічого не захоплює? У мене немає відповіді на це запитання. Я вважаю це невизначеною поведінкою, і я не хочу використовувати невизначену поведінку.


0

Гіпотетично, якщо пошук призупинив вас з цього питання, ви, мабуть, цього хочете:

doReturn(someReturn).when(someObject).doSomething(argThat(argument -> argument.getName().equals("Bob")));

Чому? Тому що, як я, ти цінуєш час і не збираєшся реалізовувати .equalsлише заради єдиного сценарію тестування.

І 99% тестів розпадаються з нульовим поверненням з Mock, і при розумному дизайні ви уникнете повернення nullбудь-якою ціною, використовуєте Optionalабо переїжджаєте до Котліна. Це означає, що verifyне потрібно використовувати це часто, і ArgumentCaptors просто надто нудно писати.

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