Глоток МоКито

    А Вы знаете что такое mock-объект? Нет?

    Что же говорит по этому поводу википедия: «В объектно-ориентированном программировании mock-объект имитирует поведение реального объекта заданным образом… ». Казалось бы зачем? Википедия продолжает: «Во время unit-тестирования mock-объекты могут симулировать поведение бизнес-объектов и бизнес-логику, что иногда необходимо из-за сложности реального поведения»


    И что же дают mock-библиотеки java-разработчику? Конечно же удобство создания и использования тех самых mock-объектов!

    java-source.net приводит список аж из 7 библиотек:

    Я начал знакомство с mock-объектами c другой библиотеки, которой нет на java-source.net — Mockito. Я просто доверился мнению javaposse, признавших mockito библиотекой недели, а так же настроению java-блогосферы и не разочаровался. Вы тоже оцените насколько это удобно:

    Внимание! Сделав глоток — остановиться невозможно.

    Проверяем поведение


    mock-объект будет запоминать любые вызовы его методов, чтобы после Вы могли проверить какие методы вызывал ваш тестируемый код у mock-объекта
    Copy Source | Copy HTML
    1. //статически импортируем методы (для красоты и легкости кода)
    2. import static org.mockito.Mockito.*;
    3.  
    4. //вот он - mock-объект (заметьте: List.class - это интерфейс)
    5. List mockedList = mock(List.class);
    6.  
    7. //используем его
    8. mockedList.add("one");
    9. mockedList.clear();
    10.  
    11. //проверяем, были ли вызваны методы add с параметром "one" и clear
    12. verify(mockedList).add("one");
    13. verify(mockedList).clear();

    А как же stub'ы?


    По умолчанию все методы mock объекта возвращают default'ные значение, false для boolean, 0 для int, пустые коллекции, null для остальных объектов.
    Copy Source | Copy HTML
    1. //Вы можете создавать mock для конкретного класса, не только для интерфейса
    2. LinkedList mockedList = mock(LinkedList.class);
    3.  
    4. //stub'инг
    5. when(mockedList.get(0)).thenReturn("first");
    6. when(mockedList.get(1)).thenThrow(new RuntimeException());
    7.  
    8. //получим "first"
    9. System.out.println(mockedList.get(0));
    10.  
    11. //получим RuntimeException
    12. System.out.println(mockedList.get(1));
    13.  
    14. //получим "null" ибо get(999) не был определен
    15. System.out.println(mockedList.get(999));

    Проверяем точное количество вызовов


    Copy Source | Copy HTML
    1. //используем mock-объект
    2. mockedList.add(«once»);
    3.  
    4. mockedList.add(«twice»);
    5. mockedList.add(«twice»);
    6.  
    7. mockedList.add(«three times»);
    8. mockedList.add(«three times»);
    9. mockedList.add(«three times»);
    10.  
    11. //по умолчанию проверка, что вызывался 1 раз ~ times(1)
    12. verify(mockedList).add(«once»);
    13. verify(mockedList, times(1)).add(«once»);
    14.  
    15. //точное число вызовов
    16. verify(mockedList, times(2)).add(«twice»);
    17. verify(mockedList, times(3)).add(«three times»);
    18.  
    19. //никогда ~ never() ~ times(0)
    20. verify(mockedList, never()).add(«never happened»);
    21.  
    22. //как минимум, как максимум
    23. verify(mockedList, atLeastOnce()).add(«three times»);
    24. verify(mockedList, atLeast(2)).add(«five times»);
    25. verify(mockedList, atMost(5)).add(«three times»);

    Паразитируем на реальных объектах


    Вы можете создать mock-объект, (точнее spy-объект) который будет использовать реальный объект при вызовах метода. Перегрузив лишь необходимые вам методы, так сказать частичный mock-объект.
    Copy Source | Copy HTML
    1. List list = new LinkedList();
    2. List spy = spy(list);
    3.  
    4. //опционально, определяем лишь метод size()
    5. when(spy.size()).thenReturn(100);
    6.  
    7. //используем реальные методы
    8. spy.add("one");
    9. spy.add("two");
    10.  
    11. //получим "one"
    12. System.out.println(spy.get(0));
    13.  
    14. //метод size() нами переопределён - получим 100
    15. System.out.println(spy.size());
    16.  
    17. //можем проверить
    18. verify(spy).add("one");
    19. verify(spy).add("two");

    А так же


    • Используем маски в аргументах переопределяемых методов
    • Переопределяем методы, возвращающие void
    • Проверяем порядок вызовов mock-объекта
    • Ищем ненужные вызовы mock-объекта
    • Аннотация Mock
    • Различные возвращаемые значения, для одних и тех же аргументов
    • остатки сладки

    Дополнительная литература:

    Спасибо. И да, в этом посте 58 раз упоминается слово mock
    Поделиться публикацией
    Реклама помогает поддерживать и развивать наши сервисы

    Подробнее
    Реклама
    Комментарии 10
    • +2
      я наверное не выспался, но мне mock померещился как:
      а знаете ли вы что такео моск-обьект? :))))
    • 0
      Если использовать мок объекты для мониторинга за живой системой, сильно ли это повлияет на производительность? Т.е. в живой работающей системе подменять «моками» объекты, за которыми хочется понаблюдать.
      • 0
        наоборот, моками заменяют объекты за которыми НЕ хочется наблюдать.
        Например, есть сервис возвращающий погоду в заданный день — для тестов мы заменяем его моком, который будет возвращать какое-то значение, что бы проверить как работает остальное.
        • 0
          да, уже разобрался, спасибо ))
      • +3
        Эх, все эти библиотеки хороши, но лучше бы была только одна стандартизированная (как junit). А то изучишь одну, а в следующем проекте окажется, что используется совсем другая — и опять переучиваться. По этой же причине и внедрение этих библиотек не велико — каждого нового человека нужно соотвествующей библиотеке обучать.
        • +1
          Есть ещё вполне удобный, хотя может менее распостранённый testng :)
          • Если есть методичка, хотя бы в виде существующих тестов, которые используют соответствующую mocking library, то новые люди учатся использовать ее весьма быстро. Как говорится, monkey see, monkey do.
          • 0
            Как насчет https://jmockit.dev.java.net/?
            • 0
              В 1990 году фирма мелодия выпустила единственную пластинку группы "Лунный пьеро", на которой была песня Страшный Мок. Читая эту статью, я убедился, что это неправда. Моки — они совсем не страшные.

              Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.