JUnit / Mockito: ArgumentCaptor работает до выполнения теста JUnit? - PullRequest
0 голосов
/ 26 февраля 2020

У меня есть тест JUnit, такой как:

@Autowired
MyService myservice;

@Before
public void init() {
   myservice.doStuff(new MyObj());
}

@Test
public void test() {
   ArgumentCaptor<MyObj> captor = ArgumentCaptor.forClass(MyObj.class);
   myservice.doStuff(new MyObj());
   verify(myservice, atLeastOnce()).doStuff(captor.capture());
   captor.getAllValues(); //this returns 2 - one for the @Before and one for right above
}

Как упомянуто в прокомментированном коде, захват захватывает оба вызова, даже если захват создается после @Before. Почему это так и как я могу захватить только вызов в тесте?

1 Ответ

1 голос
/ 26 февраля 2020

Что-то выглядит не так в этом потоке, я объясню, и, надеюсь, это приведет вас к решению:

Прежде всего, ArgumentCaptor используется только с макетами. Так что myservice должно быть насмешкой, я ожидал увидеть что-то вроде @MockBean или, возможно, @Mock, если вы проводите простой тест на мокито без пружины.

Теперь, если предположить, что это макет, зачем вызывать метод doStuff на макете в фазе @Before. Я могу понять, хотите ли вы настроить глобальные ожидания, применимые ко всем тестам в классе, если у вас их много, но мне это кажется подозрительным.

Теперь, когда вы используете verify, то, что вы на самом деле скажем так:

Mockito, убедитесь, что мой макет myservice вызвал метод doStuff (хотя бы один раз), и для дальнейшей проверки я хотел бы "захватить" аргументы, которые были переданы на макет, пока вызов (ы) метода.

При таком подходе становится понятно, что захват аргумента получает всю информацию обо всех вызовах, и я верю, что это по замыслу.

Чтобы прояснить ситуацию, @Before метод не имеет ничего общего с mockito, он является чисто JUnit-хуком, поэтому к тому моменту, когда он вызывается фреймворком JUnit, все mocks уже инициализированы и готовы «записать» всю соответствующую информацию обо всем, что будет делать код их (я имею в виду вызовы методов).

...