Table of Contents

JUnit5

Obiective

Unit testing

Unit testing-ul s-a impus în ultima perioadă în dezvoltarea proiectelor scrise în limbajul Java şi nu numai, pe măsura apariţiei unor utilitare gratuite de testare a claselor, care au contribuit la creşterea vitezei de programare şi la micşorarea semnificativă a numărului de bug-uri.

Printre avantajele folosirii framework-ului JUnit se numără:

JUnit

Reprezintă un framework de Unit Testing pentru Java.

Exemplu:

Student.java
public class Student {
 
    private String name;
    private String age;
 
    public Student(String name, String age) {
        this.name = name;
        this.age = age;
    }
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public String getAge() {
        return age;
    }
 
    public void setAge(String age) {
        this.age = age;
    }
 
}
Group.java
import java.util.ArrayList;
import java.util.List;
 
public class Group {
 
    List<Student> students;
 
    Group () {
        students = new ArrayList<Student>();
    }
 
    public List<Student> getStudents() {
        return students;
    }
 
    public void setStudents(List<Student> students) {
        this.students = students;
    }
 
    public void addStudent(Student student) {
        students.add(student);
    }
 
    public Student getStudent(String name) {
        for (Student st : students) {
            if (null != st.getName() && st.getName().equals(name)) {
                return st;
            }
        }
        return null;
    }
 
    public boolean areStudentsInGroup() {
        if (0 == students.size()) {
            return false;
        }
        return true;
    }
 
}
Test.java
import org.junit.jupiter.api.*
 
public class GroupTest {
    private Group group;
 
    @BeforeEach
    public void setup() {
        group = new Group();
    }
 
    @Test
    public void testNoStudentInGroup() {
        Assertions.assertEquals(false, group.areStudentsInGroup());
    }
 
    @Test
    public void testAddStudent() {
        Student st = new Student("Elena", "11");
        group.addStudent(st);
 
        Assertions.assertTrue(group.getStudent("Elena").equals(st));
    }
 
    @AfterEach 
    public void tearDown() {
        group = null;
    }
 
}

Observaţii:

Pentru a folosi framework-ul JUnit5, consultați tutorialul din laboratorul 8, aflat la secțiunea Unit testing.

Câteodată avem nevoie să testăm funcționalitatea unor clase ce folosesc metode din alte clase netestate sau care nu pot fi testate. De asemenea, există cazuri în care vrem sa testăm comportamentul clasei în situații extreme sau foarte greu de replicat (erori de disc, epuizarea spațiului pe disc, obținerea unei anumite valorii în cazul in care folosim generatoare random).

Pentru a rezolva ușor aceste necesități putem folosi obiecte de tip mock. Aceste obiecte simulează comporatamentul clasei mock-uite și sunt controlate din interiorul unit testelor. Pentru mai multe detalii puteți consulta pagina Mock Object.

În Java pentru a implementa mock-uri puteți folosi framework-ul JMock. Un scurt tutorial de instalare si folosire găsiți aici. Pentru exemple mai detaliate puteţi consulta cookbook-ul pus la dispozitie pe site-ul jmock.org.

Exerciţii facultative

  1. Creaţi clasa Animal şi clasa Zoo. Clasa Zoo conţine un vector de animale. Implementaţi metodele: addAnimal(Animal a), removeAnimal(Animal a), boolean areAnimals(), getAnimals(), size(). Creaţi o clasa Test unde veţi verifica diverse scenarii:
    • La rularea fiecărei metode veti instanţia clasa Zoo.
    • Metoda testAddAnimal - adaugă un obiect Animal şi verifică daca adăugarea a avut loc cu succes. Folosiţi: assertEquals
    • Metoda testRemoveAnimal - folosiţi assertTrue
    • Metoda testAreAnimalsInZoo - testul pică dacă metoda returnează false. Hint: Assert.fail()
    • Metoda testGetAnimals - adăugaţi două obiecte Animal. Verificaţi ca adăugarea a avut loc cu succes. Folosiţi assertFalse.
  2. Acest exerciţiu urmăreşte identificarea unor cazuri de test, strict pe baza specificaţiei, în absenţa accesului la codul sursă şi a cunoaşterii modului intern de funcţionare a sistemului. Se consideră o clasa GeometricForms avand un constructor ce primeste un String ce poate fi unul din valorile enum-ului Forms.
    • Adăugaţi în build path-ul proiectului clasele din scheletul de laborator.
    • Metodele isTriangle, isCircle si isRectangle au drept scop evaluarea stării obiectului GeometricForms.
    • Creaţi un scenariu de testare pentru această clasă, prin implementarea propriilor cazuri de testare, într-o clasă GeometricFormsTest.
    • Construiţi teste specializate, orientate pe o anumită funcţionalitate. De exemplu, în cadrul unui test, verificaţi doar una din cele 3 metode.
    • public enum Forms {
         TRIANGLE, CIRCLE, RECTANGLE
      }

Resurse

Referinţe