ݺߣ

ݺߣShare a Scribd company logo
Курс по Java, 2016
Reflection, Mock
java.lang.reflect, Mockito
Курс по Java, 2016
Reflection — отражение
Курс по Java, 2016
java.lang.Class
Class<String> clazz = String.class;
String s = "abc";
Class<? extends String> clazz = s.getClass();
Class<?> clazz = Class.forName("java.lang.String");
Курс по Java, 2016
java.lang.ClassLoader
ClassLoader loader = clazz.getClassLoader();
ClassLoader loader = ClassLoader.getSystemClassLoader();
Class<?> newClazz =
loader.loadClass("it.sevenbits.MyClass");
Class<?> newClazz =
Class.forName("it.sevenbits.MyClass", true, loader);
Курс по Java, 2016
Что JVM делает с .class
http://blog.jamesdbloom.com/JVMInternals.html
Курс по Java, 2016
Свой ClassLoader
class NetworkClassLoader extends ClassLoader {
public Class findClass(String name) {
byte[] b = loadClassData(name);
return defineClass(name, b, 0, b.length);
}
private byte[] loadClassData(String name) {
// откуда-то загрузить содержимое .class
}
}
Курс по Java, 2016
Создание объекта
Class<String> clazz = String.class;
String emptyString = clazz.newInstance(); // ""
Только конструктор по умолчанию
Курс по Java, 2016
Конструкторы
Class<String> clazz = String.class;
Constructor<String> constructor =
clazz.getConstructor(byte[].class, String.class);
String s = constructor.newInstance(
new byte[] {'a', 'b', 'c'}, "ascii");
assertEquals("abc", s);
Курс по Java, 2016
Конструкторы
Constructor nonPublicConstructor =
clazz.getDeclaredConstructor();
Constructor[] publicConstructors =
clazz.getConstructors();
Constructor[] allConstructors =
clazz.getDeclaredConstructors();
Курс по Java, 2016
Методы
Class<String> clazz = String.class;
Method method = clazz.getMethod("charAt", int.class);
Object obj = "abc";
Object result = method.invoke(obj, 1);
assertEquals('b', result);
Курс по Java, 2016
Методы
Method nonPublicMethod = clazz.getDeclaredMethod("clone");
Method[] publicMethods = clazz.getMethods();
Method[] allMethods = clazz.getDeclaredMethods();
Курс по Java, 2016
Поля
Class clazz = MyClass.class;
Field field = clazz.getField("myField");
Object obj = new MyClass();
Object value = field.get(obj);
assertEquals(3, value);
field.set(obj, 42);
assertEquals(42, ((MyClass)obj).myField);
Курс по Java, 2016
Доступ к приватному полю
Class clazz = MyClass.class;
Field field = clazz.getDeclaredField("privateField");
field.setAccessible(true);
Object obj = new MyClass();
field.set(obj, "new value");
Object value = field.get(obj);
assertEquals("new value", value);
Курс по Java, 2016
Исключения
ClassNotFoundException — не найдено класса
InstantiationException — не удалось создать объект
NoSuchMethodException — нет такого метода (или конструктора)
NoSuchFieldException — нет такого поля
IllegalAccessException — нет доступа к методу или полю (private)
InvocationTargetException — не получилось вызвать метод
Курс по Java, 2016
Reflection может быть медленным
http://ashkrit.blogspot.ru/2013/01/java-reflection-facts.html
Курс по Java, 2016
Курс по Java, 2016
Mockito
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>1.10.19</version>
<scope>test</scope>
</dependency>
Курс по Java, 2016
Создать заглушку
import static org.mockito.Mockito.*;
IReader mockReader = mock(IReader.class);
Курс по Java, 2016
Определить поведение заглушки
// возврат значения
when(mockReader.read()).thenReturn('a', 'b', 'c');
// выброс исключения
doThrow(Exception.class).when(mockReader).close();
Курс по Java, 2016
Определить поведение заглушки
doAnswer(new Answer() {
public Object answer(InvocationOnMock invocationOnMock)
throws Throwable {
char[] chars =
(char[]) invocationOnMock.getArguments()[0];
chars[0] = 'a'; chars[1] = 'b'; chars[2] = 'c';
return null;
}
}).when(mockReader).readArray(any(char[].class));
Курс по Java, 2016
Вызов методов заглушки
assertEquals('a', mockReader.read());
assertEquals('b', mockReader.read());
assertEquals('c', mockReader.read());
char[] chars = new char[3];
mockReader.readArray(chars);
assertArrayEquals(new char[] {'a', 'b', 'c'}, chars);
mockReader.close();
Курс по Java, 2016
Проверка вызовов заглушки
// read() вызван ровно 3 раза
verify(mockReader, times(3)).read();
// readArray вызван один раз с каким-то char[]
verify(mockReader).readArray(any(char[].class));
Курс по Java, 2016
Алгоритм работы с заглушками
// создание заглушки
IReader mockReader = mock(IReader.class);
// определение поведения (если нужно)
when(mockReader.read()).thenReturn('a');
// использование
assertEquals('a', mockReader.read());
// проверка вызовов (если нужно)
verify(mockReader).read();
Курс по Java, 2016
Домашнее задание
Написать тесты на все реализации потоков, используя Mockito.
Можно ли написать тесты на интерфейсы, чтобы проверять любую новую
реализацию, не написав для нее ни одного нового теста?
annie.tarasenko@7bits.it denis.nelubin@7bits.it

More Related Content

Курс Java-2016. Занятие 10. Reflection, mock

  • 1. Курс по Java, 2016 Reflection, Mock java.lang.reflect, Mockito
  • 2. Курс по Java, 2016 Reflection — отражение
  • 3. Курс по Java, 2016 java.lang.Class Class<String> clazz = String.class; String s = "abc"; Class<? extends String> clazz = s.getClass(); Class<?> clazz = Class.forName("java.lang.String");
  • 4. Курс по Java, 2016 java.lang.ClassLoader ClassLoader loader = clazz.getClassLoader(); ClassLoader loader = ClassLoader.getSystemClassLoader(); Class<?> newClazz = loader.loadClass("it.sevenbits.MyClass"); Class<?> newClazz = Class.forName("it.sevenbits.MyClass", true, loader);
  • 5. Курс по Java, 2016 Что JVM делает с .class http://blog.jamesdbloom.com/JVMInternals.html
  • 6. Курс по Java, 2016 Свой ClassLoader class NetworkClassLoader extends ClassLoader { public Class findClass(String name) { byte[] b = loadClassData(name); return defineClass(name, b, 0, b.length); } private byte[] loadClassData(String name) { // откуда-то загрузить содержимое .class } }
  • 7. Курс по Java, 2016 Создание объекта Class<String> clazz = String.class; String emptyString = clazz.newInstance(); // "" Только конструктор по умолчанию
  • 8. Курс по Java, 2016 Конструкторы Class<String> clazz = String.class; Constructor<String> constructor = clazz.getConstructor(byte[].class, String.class); String s = constructor.newInstance( new byte[] {'a', 'b', 'c'}, "ascii"); assertEquals("abc", s);
  • 9. Курс по Java, 2016 Конструкторы Constructor nonPublicConstructor = clazz.getDeclaredConstructor(); Constructor[] publicConstructors = clazz.getConstructors(); Constructor[] allConstructors = clazz.getDeclaredConstructors();
  • 10. Курс по Java, 2016 Методы Class<String> clazz = String.class; Method method = clazz.getMethod("charAt", int.class); Object obj = "abc"; Object result = method.invoke(obj, 1); assertEquals('b', result);
  • 11. Курс по Java, 2016 Методы Method nonPublicMethod = clazz.getDeclaredMethod("clone"); Method[] publicMethods = clazz.getMethods(); Method[] allMethods = clazz.getDeclaredMethods();
  • 12. Курс по Java, 2016 Поля Class clazz = MyClass.class; Field field = clazz.getField("myField"); Object obj = new MyClass(); Object value = field.get(obj); assertEquals(3, value); field.set(obj, 42); assertEquals(42, ((MyClass)obj).myField);
  • 13. Курс по Java, 2016 Доступ к приватному полю Class clazz = MyClass.class; Field field = clazz.getDeclaredField("privateField"); field.setAccessible(true); Object obj = new MyClass(); field.set(obj, "new value"); Object value = field.get(obj); assertEquals("new value", value);
  • 14. Курс по Java, 2016 Исключения ClassNotFoundException — не найдено класса InstantiationException — не удалось создать объект NoSuchMethodException — нет такого метода (или конструктора) NoSuchFieldException — нет такого поля IllegalAccessException — нет доступа к методу или полю (private) InvocationTargetException — не получилось вызвать метод
  • 15. Курс по Java, 2016 Reflection может быть медленным http://ashkrit.blogspot.ru/2013/01/java-reflection-facts.html
  • 17. Курс по Java, 2016 Mockito <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-core</artifactId> <version>1.10.19</version> <scope>test</scope> </dependency>
  • 18. Курс по Java, 2016 Создать заглушку import static org.mockito.Mockito.*; IReader mockReader = mock(IReader.class);
  • 19. Курс по Java, 2016 Определить поведение заглушки // возврат значения when(mockReader.read()).thenReturn('a', 'b', 'c'); // выброс исключения doThrow(Exception.class).when(mockReader).close();
  • 20. Курс по Java, 2016 Определить поведение заглушки doAnswer(new Answer() { public Object answer(InvocationOnMock invocationOnMock) throws Throwable { char[] chars = (char[]) invocationOnMock.getArguments()[0]; chars[0] = 'a'; chars[1] = 'b'; chars[2] = 'c'; return null; } }).when(mockReader).readArray(any(char[].class));
  • 21. Курс по Java, 2016 Вызов методов заглушки assertEquals('a', mockReader.read()); assertEquals('b', mockReader.read()); assertEquals('c', mockReader.read()); char[] chars = new char[3]; mockReader.readArray(chars); assertArrayEquals(new char[] {'a', 'b', 'c'}, chars); mockReader.close();
  • 22. Курс по Java, 2016 Проверка вызовов заглушки // read() вызван ровно 3 раза verify(mockReader, times(3)).read(); // readArray вызван один раз с каким-то char[] verify(mockReader).readArray(any(char[].class));
  • 23. Курс по Java, 2016 Алгоритм работы с заглушками // создание заглушки IReader mockReader = mock(IReader.class); // определение поведения (если нужно) when(mockReader.read()).thenReturn('a'); // использование assertEquals('a', mockReader.read()); // проверка вызовов (если нужно) verify(mockReader).read();
  • 24. Курс по Java, 2016 Домашнее задание Написать тесты на все реализации потоков, используя Mockito. Можно ли написать тесты на интерфейсы, чтобы проверять любую новую реализацию, не написав для нее ни одного нового теста? annie.tarasenko@7bits.it denis.nelubin@7bits.it