QA & Automation - Intro to Java - part 4

Exceptions & JUnit

Въпроси за загрявка

Какво ни дават Generic Types в Java? Какъв пример може да дадем за тяхното използване?

Възможност да параметризираме клас по тип. Така имаме променлив тип, който се задава при създаване на инстанция от този клас. Пример - ArrayList<Integer>

Въпроси за загрявка

Колко интерфейса може да имплементира един клас?

0, 1 или повече. Всеки интерфейс, който имплементираме ни дава възможност нашият клас да има различно поведение.

Въпроси за загрявка

Какво представлява наследяването на класове в Java?

Взимаме всичко public и protected от наследения клас. Така може да преизползваме код. Така може да постигнем и полиморфно поведение.

Въпроси за загрявка

Кой е базовият клас в йерархията на наследяване в Java?

Object. От него идват методи катo toString() и equals()

Въпроси за загрявка

Ако искаме да направим метод, който приема всякакъв тип, от какъв тип трябва да дефинираме аргумента?

Object. Тъй като всичко наследява Object, то всичко може да бъде Object.

Въпроси за загрявка

Може ли да предефинираме наследен метод?

Да. Нарича се method overring и се използва много.

Въпроси за загрявка

Ако решим да предефинираме наследен метод, но все пак искаме да извикаме наследената му версия, как става това? 

Чрез super.methodName()

Въпроси за загрявка

Ако решим да предефинираме наследен метод, но все пак искаме да извикаме наследената му версия, как става това? 

Чрез super.methodName()

Въпроси за загрявка

Какво представлява super?

Това е this–а на наследения клас. Чрез super може да викаме неща, специфични само за класа, който наследяваме.

Въпроси за загрявка

Какво представлява абстрактния клас?

Клас, от който не може да вдигаме инстанция. В него може да дефинираме абстракни методи, които трябва да бъдат имплементирани в първия не-абстрактен наследник.

Въпроси за загрявка

Може ли да имаме имплементирани методи в абстрактен клас?

Да. Това е и основната му разлика с Interface-a.

Въпроси за загрявка

Кога е възможно
T1 t = new T2(); ?

  1. Когато T1 е интерфейс, който се имплементира от T2 или от някой от класовете, които T2 наследява.
  2. Когато T1 е клас, който се наследява, директно или индиректно, от T2

Java Exceptions

  1. Изключенията не са изключителни. Винаги се случват.

  2. Когато нещо "гръмне", обикновено потребителят го отнася

  3. Изключенията са нашият механизъм, за да съобщаваме за грешки и да се възстановяваме от грешки.

Java Exceptions

  1. Изключенията в Java представляват класове и си имат йерархия.

  2. Eclipse се грижи да хваща голям обхват от грешки. Обаче ако нещо гръмне "Run time", то ние трябва да разполагаме с начин да се справим с този проблем.

  3. Това се случва със синтактичните конструкции, които Java предоставя.

Имаме няколко основни вида изключения

  1. Checked exceptions - такива, които задължително трябва да хванем.

  2. Unchecked exceptions - всички наследници на Error и RuntimeException. Тук не сме задължени да хващаме.

Checked Exeptions

  1. Това са изключения, които може да предвидим и да се възстановим след тяхното случване

  2. Например - файлът го няма, става грешка при четене на някакъв поток от данни и т.н.

  3. Java ни задължава да хващаме checked exceptions.

Checked Exeptions

public static void main(String[] args) {
  Path path = Paths.get("/home/radorado/code/Loki/README.md");
  List<String> lines = Files.readAllLines(path);
		
  System.out.println(lines);
}

В този код имаме checked exception. Имаме 2 варианта за справяне с проблема.

1) Throws Declaration

public static void main(String[] args) throws IOException {
  Path path = Paths.get("/home/radorado/code/Loki/README.md");
  List<String> lines = Files.readAllLines(path);
		
  System.out.println(lines);
}

Маркираме метода, че МОЖЕ да хвърли този вид изключение. Който вика метода, трябва да се справи по някакъв начин с него.

2) Try/Catch block

public static void main(String[] args) {
 Path path = Paths.get("/home/radorado/code/Loki/README.md");
 List<String> lines = null;
		
  try {
    lines = Files.readAllLines(path);
  } catch (IOException e) {
    e.printStackTrace();
  }
		
  System.out.println(lines);
}

Try/Catch block

try {
// some code that throws exception
} catch (Exception e) {
// do something with exception
}
  1. Ако код в try хвърли exception, ще се опитаме да го хванем в catch блока.
  2. Ще успеем да го хванем, ако сме дефинирали catch блок с тип на Exception-а, които да е възможен.
  3. Тук важи правилото за полиморфизма.

Try/Catch block

try {
// some code that throws exception
} catch (ExceptionType1 e) {
// do something with exception
} catch (ExceptionType2 e) {
// do something with exception
} ... catch (ExceptionTypeN e) {
// do something with exception
}

Може да имаме повече от 1 catch block - хващайки различни типове exceptions. catch-а се извършва по ред на дефиниране на catch блоковете.

Try/Catch block

try {
// some code that throws exception
} catch (Exception e) {
// do something with exception
} catch(IOException e) {

}

Това е невалиден код, защото първо хващаме по-общият вид, а след това по-конкретният вид. Трябва да са наобратно.

Try/Catch/Finally

public static void main(String[] args) {
  Path path = Paths.get("/missing/file");
  List<String> lines = null;
		
  try {
    lines = Files.readAllLines(path);
  } catch(Exception e) {
    System.out.println(e.toString());
    // java.nio.file.NoSuchFileException: /missing/file
  } finally {
    System.out.println("Finally");
    // Finally
  }
		
  System.out.println(lines);
  // null
}

finally block–а винаги се изпълнява.

Unckeched Exceptions

  1. Java не ни задължава да ги хващаме

  2. Често са резултат от лошо написан код или наличие на бъгове

  3. NullPointerException е класиката тук.

  4. Заедно с IndexOutOfBounds и ClassCastException

  5. Прочете това.

Unckeched Exceptions

  1. От Unchecked Exception се възстановяваме по-трудно.

  2. Ако имаме NullPointerException, а ни трябва обекта, за да продължим - какво правим?

  3. Това налага стил на писане с много "null checks". Проверяваме дали нещо не е null, преди да го извикаме.

  4. Ако пък е null, често не знаем какво да правим - попаднали сме в лош state.

Unit Testing, TDD & JUnit

  1. Unit Testing–а ни позволява да проверим дали даден обект, при определени действия, дава очакван резултат / състояние

  2. Пишем го като код, а не на ръка. Ако напишем един тест, то той ще продължава да се пуска при нов код и нови тестове.

  3. Това ни пази от регресия.

  4. Регресията може да ви докара до болест. Да ви накара да не вярвате на хората. Да ви подули.

Unit Testing, TDD & JUnit

  1. Почти във всеки език / платформа имаме *Unit библиотека, с която може да пишем unit тестове.

  2. Там очакваме assertEquals, setUp и tearDown под някаква форма. Това е всичко, което ни стига.

  3. В Java работим с JUnit

TDD - когато ни трябва малко дисциплина

TDD - демонстрация с JUnit

QA & Automation - Intro to Java - part 4

By Hack Bulgaria

QA & Automation - Intro to Java - part 4

  • 1,617