Тестирование 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.впрыскивать.пример или что-то еще.