Тестирование Java улучшено для поведения с Mockito
Я хочу протестировать метод java, который имеет улучшенное для него использование Mockito. Проблема в том, что когда я не знаю, как установить ожидания для расширенного для работы. Следующий код был получен из вопрос без ответа в группе mockito google:
import static org.mockito.Mockito.when;
import static org.testng.Assert.assertTrue;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.mockito.Mockito;
import org.testng.annotations.Test;
public class ListTest
{
@Test
public void test()
{
List<String> mockList = Mockito.mock(List.class);
Iterator<String> mockIterator = Mockito.mock(Iterator.class);
when(mockList.iterator()).thenReturn(mockIter);
when(mockIter.hasNext()).thenReturn(true).thenReturn(false);
when(mockIter.next()).thenReturn("A");
boolean flag = false;
for(String s : mockList) {
flag = true;
}
assertTrue(flag);
}
}
код внутри цикла не выполняется. Установка ожиданий для итератора не работает, потому что Java enhanced for не использует итератор списка внутренне. Установочный ожидания List.get()
метод Не либо с усиленной по реализации не называть get()
способ из списка.
любая помощь будет высоко ценится.
4 ответов
издевательство над итератором работает для меня. См. ниже пример кода:
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.util.Collection;
import java.util.Iterator;
import org.junit.Before;
import org.junit.Test;
public class TestMockedIterator {
private Collection<String> fruits;
private Iterator<String> fruitIterator;
@SuppressWarnings("unchecked")
@Before
public void setUp() {
fruitIterator = mock(Iterator.class);
when(fruitIterator.hasNext()).thenReturn(true, true, true, false);
when(fruitIterator.next()).thenReturn("Apple")
.thenReturn("Banana").thenReturn("Pear");
fruits = mock(Collection.class);
when(fruits.iterator()).thenReturn(fruitIterator);
}
@Test
public void test() {
int iterations = 0;
for (String fruit : fruits) {
iterations++;
}
assertEquals(3, iterations);
}
}
Если я чего-то не хватает, вы, вероятно, должны возвращать реальный список издевательских значений. В этом случае создайте свой список тестовой строки в методе генератора и просто верните его. В более сложных случаях можно заменить содержимое списка издевательскими объектами.
в качестве заключительной точки я не могу себе представить, почему вам когда-либо действительно нужно было бы издеваться над улучшенным циклом for. Характер модульных тестов не поддается такому уровню проверки. Это интересно тем не менее, вопрос.
просто хочу кое-что уточнить, потому что я боролся с этим весь день:
Если вы хотите использовать myList.forEach(...)
синтаксис вместо for(:)
, вы должны включить (где вы настроили свой издевательский список):
doCallRealMethod().when(myMockedList).forEach(anyObject());
вы хотите сделать что-то подобное.
/**
* THe mock you want to make iterable
*/
@Mock
javax.inject.Instance<Integer> myMockedInstanceObject;
/**
* Setup the myMockedInstanceObject mock to be iterable when the business logic
* wants to loop existing instances of the on the iterable....
*/
private void setupTransportOrderToTransportEquipmentMapperInstancesToBeIteratble() {
// (a) create a very real iterator object
final Iterator<Integer> iterator = Arrays
.asList(Integer.valueOf(1), Integer.valueOf(2)).iterator();
// (b) make sure your mock when looped over returns a proper iterator
Mockito.doAnswer(new Answer<Iterator<Integer>>() {
@Override
public Iterator<Integer> answer(InvocationOnMock invocation)
throws Throwable {
return iterator;
}
}).when(myMockedInstanceObject).iterator();
}
строка coments и javadoc должны дать достаточно ясно понять, как издеваться над поведением Любой итерации, независимо от того, что это список, коллекция javax.впрыскивать.пример или что-то еще.