Mockito.mock(...) позволяет динамически создать экземпляр, с классом, который является подклассом переданного класса. Если мы сделаем
System.out.println(listMock.getClass());
то увидим нечто вроде
$java.util.List$$EnhancerByMockitoWithCGLIB$$29cb8e61
Можно увидеть прямую аналогию с java.lang.reflet.Proxy:
List list = Proxy.newProxyInstance(..., new Class[]{List.class}, handler);
Но в данном случае мы не передаем handler.
Каково же поведение полученного mock?
Stubbed методы по умолчанию возвращают null, 0, false в зависимости от типа.
Одна из удивительных способностей Mockito состоит в том, что можно "красиво" определять, что будет возвращать stubbed метод:
Но, если мы попробуем вызвать для "незнакомого" аргумента, то получим значение по умолчанию.
>> null
Вы можем переопределить значение по умолчанию
>> "stub"
Демонстрация установки более сложного поведения:
>> "even"
Добавим немного static import и посмотрим на результат:
Вторая удивительная особенность Mockito состоит в том, что мы может "опросить" моки после использования - "что они пережили".
- Сайт Mockito
- 22 примера из javadoc класса org.mockito.Mockito
Задания для углубленного изучения
- разберитесь в разнице между Dummy, Fake, Stub, Mock, Spy. Будьте в состоянии привести примеры (Refcard, Fawler).
- This process of defining how a given mock method should behave is called stubbing.
- разберитесь в отличии mock(..).thenReturn(..) и mock(..).thenAnswer(..)
- arrange-act-assert cycle
- BDD vs TDD
- argument matching (ArgumentMatcher, argThat(..))
- result matching
- логические операции AND/OR/NOT над mather-ами ()
System.out.println(listMock.getClass());
то увидим нечто вроде
$java.util.List$$EnhancerByMockitoWithCGLIB$$29cb8e61
import org.mockito.Mockito;
import java.util.List;
public class MockitoDemo0 {
public static void main(String[] args) {
// arrange
List<String> listMock = Mockito.mock(List.class);
// act
System.out.println(listMock.getClass());
}
}
В качестве аргумента метода mock() можно передавать как классы, так и интерфейсы.Можно увидеть прямую аналогию с java.lang.reflet.Proxy:
List list = Proxy.newProxyInstance(..., new Class[]{List.class}, handler);
Но в данном случае мы не передаем handler.
Каково же поведение полученного mock?
import org.mockito.Mockito;
import java.util.List;
public class MockitoDemo1 {
public static void main(String[] args) {
// arrange
List<String> listMock = Mockito.mock(List.class);
// act
System.out.println(listMock.get(0));
}
}
Данная программа выведет
>> nullStubbed методы по умолчанию возвращают null, 0, false в зависимости от типа.
Одна из удивительных способностей Mockito состоит в том, что можно "красиво" определять, что будет возвращать stubbed метод:
import org.mockito.Mockito;
import java.util.List;
public class MockitoDemo2 {
public static void main(String[] args) {
// arrange
List<String> listMock = Mockito.mock(List.class);
Mockito.when(listMock.get(0)).thenReturn("stub");
// act
System.out.println(listMock.get(0)); // pring "stub"
}
}
Данная программа выведет
>> "stub"Но, если мы попробуем вызвать для "незнакомого" аргумента, то получим значение по умолчанию.
import org.mockito.Mockito;
import java.util.List;
public class MockitoDemo3 {
public static void main(String[] args) {
// arrange
List<String> listMock = Mockito.mock(List.class);
Mockito.when(listMock.get(0)).thenReturn("stub");
// act
System.out.println(listMock.get(0));
System.out.println(listMock.get(1));
}
}
Данная программа выведет
>> "stub">> null
Вы можем переопределить значение по умолчанию
import org.mockito.Mockito;
import java.util.List;
public class MockitoDemo4 {
public static void main(String[] args) {
// arrange
List<String> listMock = Mockito.mock(List.class);
Mockito.when(listMock.get(Mockito.anyInt())).thenReturn("stub");
// act
System.out.println(listMock.get(0));
System.out.println(listMock.get(1));
}
}
Данная программа выведет
>> "stub">> "stub"
Демонстрация установки более сложного поведения:
import org.mockito.ArgumentMatcher;
import org.mockito.Mockito;
import java.util.List;
public class MockitoDemo5 {
public static void main(String[] args) {
// arrange
List<String> listMock = Mockito.mock(List.class);
Mockito.when(listMock.get(Mockito.anyInt())).thenReturn("odd");
Mockito.when(listMock.get(evenInt())).thenReturn("even");
// act
System.out.println(listMock.get(0));
System.out.println(listMock.get(1));
}
private static int evenInt() {
return Mockito.intThat(new ArgumentMatcher<Integer>() {
@Override
public boolean matches(Object arg) {
return ((Integer) arg) % 2 == 0;
}
});
}
}
Данная программа выведет
>> "odd">> "even"
Добавим немного static import и посмотрим на результат:
import org.mockito.ArgumentMatcher;
import org.mockito.Mockito;
import java.util.List;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class MockitoDemo6 {
public static void main(String[] args) {
// arrange
List<String> listMock = mock(List.class);
when(listMock.get(anyInt())).thenReturn("odd");
when(listMock.get(evenInt())).thenReturn("even");
// act
System.out.println(listMock.get(0)); // print "even"
System.out.println(listMock.get(1)); // print "odd"
}
private static int evenInt() {
return Mockito.intThat(
new ArgumentMatcher<Integer>() {
@Override
public boolean matches(Object arg) {
return ((Integer) arg) % 2 == 0;
}
});
}
}
Красота!
Вторая удивительная особенность Mockito состоит в том, что мы может "опросить" моки после использования - "что они пережили".
м
Материалы
- Сайт Mockito
- 22 примера из javadoc класса org.mockito.Mockito
Задания для углубленного изучения
- разберитесь в разнице между Dummy, Fake, Stub, Mock, Spy. Будьте в состоянии привести примеры (Refcard, Fawler).
- This process of defining how a given mock method should behave is called stubbing.
- разберитесь в отличии mock(..).thenReturn(..) и mock(..).thenAnswer(..)
- arrange-act-assert cycle
- BDD vs TDD
- argument matching (ArgumentMatcher, argThat(..))
- result matching
- логические операции AND/OR/NOT над mather-ами ()