Lab#SE00-1: Maven Person

Java SE Lab 02 part 1

javase
lab
composition
model
Java SE Lab 02, part 1 work on the Model
Author

Victor Calvache

Published

Monday, December 19, 2022

Modified

Monday, May 15, 2023

1 Goal

The goal of this project consist on creating different Java Classes, learn about Composition in Java Classes and testing.


2 Tasks

📘 Java SE Lab#SE00-1: Person

  1. Create a Maven/Gradle Java SE Project with the UML and classes defined below.

  2. Add Lombok, JUnit and Faker dependencies

  3. Refactor: remove boilerplate code (getters, setters and so on) and work with Lombok

  4. Create Junit tests to test objects. Use Faker to create objects:

    1. Test createPerson: check whether the object Person creation works properly.
    2. Test createCar: check whether the object Car creation works properly.
    3. Test createBook: check whether the object Book creation works properly.
    4. Test createStudent: check whether the object Student creation works properly
    5. Without composition: a Student object without car and books.
    6. With composition: a Student object with Car object and Book List objects
  5. Create Junit tests to test operations:

    1. Test methodsPerson: check that Person methods work properly: becomeOlder(), killVampire(), withFirstName()
  6. Improve Car, Book and Author classes with two methods each.


3 UML

classDiagram
class Person {
  -firstname: String
  -lastname: String
  -age: int
}
class Student {
  -university: String
  -car: Car
  -books: ArrayList~Book~

}
class Author {
  -genre: String
  -book: Book
}

class Car{
    -places: int
    -color: String
}

class Book{
    -title: String
    -ISBN: String
    -pages: int
    -ahutor: Author
}
Person --|> Student: Inheritance
Person --|> Author: Inheritance
Student *-- Book: Composition
Book *-- Author: Composition
Student *-- Car: Composition
Author *-- Book: Composition


4 Classes

4.1 Person class

Person class with Lombok constructors and two custom constructors.

Person.java
package org.example;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Person {
    private String firstName;
    private String lastName;
    private int age;

    private boolean isVampire = false;

    public Person (String firstName, String lastName){
        this.firstName = firstName;
        this.lastName = lastName;
    }

    public Person (String firstName, String lastName, int age){
        this.firstName = firstName;
        this.lastName = lastName;
        this.age = age;
    }

4.2 Student class

Student class with Lombok constructor and one custom constructorr calling the Person super class.

Student.java
package org.example;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.ArrayList;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student extends Person{
    private String university;
    private Car car;
    private ArrayList<Book> books;

    public Student(String firstName, String lastName, int age, String university){
        super(firstName, lastName, age, false);
        this.university = university;
        this.car = new Car();
        this.books = new ArrayList<>();
    }

4.3 Student class without composition

Student class with Lombok constructor and one custom constructor calling the Person super class. No compisiton with car and book class.

StudentWithoutCompositon.java
package org.example;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class StudentNoComposition extends Person{
    private String university;

    public StudentNoComposition(String firstName, String lastName, int age, String university){
        super(firstName, lastName, age, false);
        this.university = university;
    }

4.4 Author class

Author class with Lombok constructor and one custom constructor calling the Person super class.

Author.java
package org.example;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Author extends Person{
    private String genre;
    private Book book;
    private ArrayList<Book> bookList;

    public Author (String firstName, String lastName, int age, String genre){
        super(firstName, lastName, age, false);
        this.genre = genre;
        this.book = new Book();
        this.bookList = new ArrayList<>();
    }

4.5 Car class

Car class with Lombok constructors.

Car.java
package org.example;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Car {
    private int seats;
    private int doors;
    private String color;
    private int passengers;

    public Car(int seats, int doors, String color) {
        this.seats = seats;
        this.doors = doors;
        this.color = color;
        this.passengers = 0;
    }

4.6 Book class

Book class with Lombok constructors and a custom constructor.

Book.java
package org.example;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Book {
    private String title;
    private String ISBN;
    private int pages;
    private Author author;
    private int readPages;
    private boolean bookRead;

    public Book (String title, String ISBN, int pages){
        this.title = title;
        this.ISBN = ISBN;
        this.pages = pages;
        this.author = new Author();
        this.bookRead = false;
        this.readPages = 0;
    } 

5 New methods and testing

5.1 Methods for Person class

Person class has new methods:

- withFirstName() returns a new Person object with firstName as parameter and a null lastName.
- withLastName() returns a new Person object with lastName as parameter and a null firstName.
- becomeOlder() adds 5 to age value and turns a person in a vampire ir age reaches 138 value.
- askIfVampore() checks if a person is a vampire.
- killVampire() recives a person object and kills vampire if is a vampire.
Person.java

    @Test
    public void becomeOlderTest(){
        Faker fake = new Faker();

        Person fakePerson = new Person(fake.name().firstName(), fake.name().lastName(),
                fake.number().numberBetween(1, 15));
        int originalAge = fakePerson.getAge();
        assertEquals(originalAge, fakePerson.getAge());
        fakePerson.becomeOlder();
        fakePerson.becomeOlder();
        fakePerson.becomeOlder();
        int newAge = originalAge + (5 * 3);
        assertEquals(newAge, fakePerson.getAge());
    }

    @Test
    public void withFirstNameTest(){
        Faker faker = new Faker();
        String firstName= faker.name().firstName();
        Person person = new Person();
        person = person.withFirstName(firstName);
        assertEquals(firstName, person.getFirstName());
    }

    @Test
    public void withLastNameTest(){
        Faker faker = new Faker();
        String lastName = faker.name().lastName();

        Person person = new Person();
        person = person.witLastName(lastName);
        assertEquals(lastName, person.getLastName());
    }

    @Test
    public void askIfVampireTest(){
        Faker fake = new Faker();

        Person fakeVampire = new Person(fake.name().firstName(), fake.name().lastName(),
                fake.number().numberBetween(150, 200));
        fakeVampire.becomeOlder();
        assertEquals("This person is a vampire!", fakeVampire.askIfVampire());
    }

    @Test
    public void killVampireTest(){
        Faker fake = new Faker();

        Person fakeVampire = new Person(fake.name().firstName(), fake.name().lastName(),
                fake.number().numberBetween(150, 200));
        fakeVampire.becomeOlder();
        fakeVampire.killVampire();
        assertEquals(0, fakeVampire.getAge());
    }

5.2 New methods for Student class

Student class has new methods:

- changesUniversity() recives a String and changes university of the student.
- buyBook() recives a  Book object and add the book to the booksList
Student.java
    public void changesUniversity(String university){
        this.university = university;
    }
    
    public void buyBook(Book book){
        this.books.add(book);
    }
 

5.2.1 Testing Studen Class methods

StudentClassTest.java
  @Test
    public void changesUniversityTest(){
        Faker faker = new Faker();

        Student fakeStudent = new Student(faker.name().firstName(), faker.name().lastName(), faker.number().numberBetween(1, 100),
                faker.university().name());

        String originalUniversity = fakeStudent.getUniversity();

        String newUniversity = faker.university().name();
        fakeStudent.changesUniversity(newUniversity);
        assertNotEquals(originalUniversity, fakeStudent.getUniversity());
    }

    @Test
    public void buyBook(){
        Faker faker = new Faker();

        Student fakeStudent = new Student(faker.name().firstName(), faker.name().lastName(), faker.number().numberBetween(1, 100),
                faker.university().name());

        Book fakeBook = new Book(faker.book().title(), "12345NB", faker.number().numberBetween(0, 500));

        fakeStudent.buyBook(fakeBook);
        assertEquals(fakeBook.toString(), fakeStudent.getBooks().get(0).toString());
    }
 

5.3 New methods for Author class

Author class has new methods:

- authorWritesNewBook() recives parameters and returns a new book.
- addBooksToList() recives a  Book object and add the book to the booksList.
- getOneBook() finds a book of the author that matches the bookTitle.
Author.java
    public Book authorWritesNewBook(String title, String ISBN, int pages){
        return new Book(title, ISBN, pages);
    }

    public void addBooksToList(Book book){
        this.bookList.add(book);
    }

    public Book getOneBook(String title){
        for (Book book: this.bookList){
            if (book.getTitle().equals(title)){
                return book;
            }
        }
        return null;
    }

5.3.1 Testing Author Class methods

AuthorClassTest.java
    @Test
    public void authorWritesNewBookTest(){
        Faker faker = new Faker();
        Author fakeAuthor = new Author(faker.name().firstName(), faker.name().lastName(), faker.number().randomDigit(),
                faker.book().genre());
        String bookTitle = faker.book().title();
        String ISBN = faker.idNumber().toString();
        int pages = faker.number().randomDigit();

        Book book = new Book(bookTitle, ISBN, pages);
        Book newBookByAuthor = fakeAuthor.authorWritesNewBook(bookTitle, ISBN, pages);
        assertEquals(book.getTitle(), newBookByAuthor.getTitle());
        assertEquals(book.getISBN(), newBookByAuthor.getISBN());
        assertEquals(book.getPages(), newBookByAuthor.getPages());
    }

    @Test
    public void getOneBookTest(){

        Faker faker = new Faker();
        Author fakeAuthor = new Author(faker.name().firstName(), faker.name().lastName(), faker.number().randomDigit(),
                faker.book().genre());

        for (int i = 0; i < 10; i++){
             Book fakeBook = new Book(faker.book().title(), "12345NB", faker.number().numberBetween(100, 500));
             fakeAuthor.addBooksToList(fakeBook);
        }
        Book toFind= fakeAuthor.getBookList().get(5);
        assertEquals(toFind, fakeAuthor.getOneBook(toFind.getTitle()));
    }

5.4 New methods for Car class

Car class has two new methods:

- getInTheCa() checks if there's seat or not to enter the car.
- startTheCar() if all the seats are occupied, the car start.
car.java
    public void getInTheCar() {
        if (passengers < seats) {
            this.passengers++;
        }
    }

    public String startTheCar(){
        if (passengers == seats){
            return "Let's drive!";
        } else {
            return "The car must be full to start driving";
        }
    }

5.4.1 Testing Car Class methods

CarClassTest.java
    @Test
    public void getInTheCarTest() {

        // Creating a new person object and passing all parameters
        Car fakeCar = new Car(4, 3, "Red");

        assertEquals(0, fakeCar.getPassengers());
        fakeCar.getInTheCar();
        assertEquals(1, fakeCar.getPassengers());
        fakeCar.getInTheCar();
        assertEquals(2, fakeCar.getPassengers());
        fakeCar.getInTheCar();
        assertEquals(3, fakeCar.getPassengers());
        fakeCar.getInTheCar();
        assertEquals(4, fakeCar.getPassengers());
        fakeCar.getInTheCar();
        assertNotEquals(5, fakeCar.getPassengers());

    }

    @Test
    public void startTheCarTest(){
        Car fakeCar = new Car(4, 3, "Red");

        for (int i = 0; i < fakeCar.getSeats(); i++){
            fakeCar.getInTheCar();
        }

        String isTheCarReady = fakeCar.startTheCar();
        assertEquals(isTheCarReady, fakeCar.startTheCar());
    }

5.5 New methods for Book class

Book class has new methods:

- readBook() counts how many pages of the book has been read.
- finishedBook() checks if a book is finished or not.
Book.java
    public String  readBook(int pages){
        this.readPages += pages;

        return (readPages- pages) + " remaining to finish the book";
    }

    public Boolean finishedBook(){
        if (readPages >= pages){
             this.bookRead = true;
        } else {
            this.bookRead = false;
        }
        return bookRead;
    }

5.5.1 Testing Book Class methods

BookClassTest.java
  @Test
    public void readTBookTest(){
        Faker faker = new Faker();

        Book fakeBook = new Book(faker.book().title(), "12345NB", faker.number().numberBetween(0, 500));
        int initialReadPages = fakeBook.getReadPages();
        fakeBook.readBook(50);
        assertEquals((initialReadPages + 50), fakeBook.getReadPages());

    }

    @Test
    public void finishedBookTest(){
        Faker faker = new Faker();

        Book fakeBook = new Book(faker.book().title(), "12345NB", faker.number().numberBetween(0, 500));
        fakeBook.readBook(600);
        assertEquals(true, fakeBook.finishedBook());
    }

6 GitHub repository

You can read, fork and test the code on my GitHub repo