Как высмеять метод возврата void, влияющий на объект
Я пишу модульные тесты для своего приложения, и мне было интересно, возможно ли, чтобы структура Mockito влияла на объект, который передается в метод, который возвращает пустоту из издевающегося класса. Например, вызывая издевательский класс проверки, содержащий метод, который возвращает void, но отслеживает различные изменения и метаданные через объект, переданный в качестве аргумента..
public GetCartItemsOutput getCartItems(GetCartItemsInput getCartItemsInput) {
CartItemsFilter cartItemsFilter = new CartItemsFilter();
validator.validateCartItemsInput(getCartItemsInput, cartItemsFilter); ...
Я издевался над классом валидатора для других моих тестов, но для этого мне нужно mock изменения в объекте cartItemsFilter, который я не знаю, как это сделать.
Ответы
Ответ 1
Ответ - да, вы можете, и в основном есть два уровня выполнения этого, основанные на необходимости вашего теста.
Если вы просто хотите проверить взаимодействие с имитируемым объектом, вы можете просто использовать метод verify()
, чтобы убедиться, что был вызван метод void.
Если вашему тесту действительно нужен смоделированный объект для изменения переданных ему параметров, вам необходимо реализовать Answer
:
Отредактировано, чтобы показать правильную форму использования ответа с пустым методом
doAnswer(new Answer() {
@Override
Object answer(InvocationOnMock invocation) {
Object[] args = invocation.getArguments();
((MyClass)args[0]).myClassSetMyField(NEW_VALUE);
return null; // void method, so return null
}
}).when(mock).someMethod();
В Java 8+ вышеупомянутое упрощено с помощью лямбды:
doAnswer(invocation-> {
Object[] args = invocation.getArguments();
((MyClass)args[0]).myClassSetMyField(NEW_VALUE);
return null;
}).when(mock).someMethod();
Ответ 2
Чтобы добавить к Кевину Уэлкеру ответ,
если ваш MyClass является настраиваемым классом, тогда определите в нем метод equals/hashcode, так что Mockito может использовать его для соответствия точному вызову метода.
В моем случае "MyClass" был в стороннем API, поэтому мне пришлось использовать метод "any", как показано ниже -
doAnswer(new Answer() {
Object answer(InvocationOnMock invocation) {
Object[] args = invocation.getArguments();
((MyClass)args[0]).myClassSetMyField(NEW_VALUE);
return null; // void method, so return null
}
}).when(mock).someMethod(any(MyClass.class));
Ответ 3
Также может помочь ArgumentCaptor.
Здесь фрагмент найден из здесь:
ArgumentCaptor<GetCartItemsInput > argument = ArgumentCaptor.forClass(GetCartItemsInput .class);
verify(mock).getCartItems(argument.capture());
assertEquals(cartItemsFilter, argument.getValue());