Testowanie i integracja
Część sekcji Programowanie obiektowe ścieżki Java w Coddy. Lekcja 83 z 87.
Wyzwanie
ŁatwyGratulacje z okazji zbudowania systemu zarządzania biblioteką! Czas połączyć wszystkie elementy i sprawdzić, czy wszystkie komponenty działają poprawnie jako zintegrowany system. Przygotujesz kompleksowy scenariusz testowy, który sprawdzi wszystkie funkcje zbudowane w trakcie tego projektu.
Będziesz pracować ze wszystkimi siedmioma plikami z ukończonego systemu:
Book.java: Twoja klasa Book z polami isbn, title, author, isAvailable, borrowedBy oraz wszystkimi powiązanymi metodami, w tymgetDetails().User.java: Twoja klasa User z polami id, name, listą borrowedBooks oraz metodami wypożyczania i zwracania książek.LibraryException.java: Twoja bazowa klasa niestandardowego wyjątku.BookNotAvailableException.java: Twój wyjątek dotyczący niedostępnych książek.LibraryAdmin.java: Twój interfejs administracyjny oraz implementacja AdminService.Library.java: Twoja kompletna klasa Library ze wszystkimi metodami: dodawaniem i usuwaniem książek, rejestrowaniem użytkowników, wypożyczaniem i zwracaniem książek, wyszukiwaniem oraz obsługą wyjątków.Main.java: Twój test integracyjny, który zademonstruje działanie całego systemu.
W klasie Main przetworzysz serię poleceń testujących wszystkie najważniejsze funkcje systemu bibliotecznego. Polecenia są przekazywane jako pojedynczy ciąg znaków rozdzielony przecinkami, w następujących formatach:
ADD_BOOK:isbn:title:author- Dodaj książkę za pośrednictwem AdminServiceREGISTER_USER:id:name- Zarejestruj użytkownika za pośrednictwem AdminServiceBORROW:userId:isbn- Wypożycz książkę (z obsługą wyjątków)RETURN:userId:isbn- Zwróć książkęSEARCH_TITLE:keyword- Wyszukaj książki według tytułuSEARCH_AUTHOR:keyword- Wyszukaj książki według autoraREMOVE_BOOK:isbn- Usuń książkę za pośrednictwem AdminService
Przetwórz każde polecenie i wyświetl odpowiedni wynik:
- ADD_BOOK:
Added: [title] - REGISTER_USER:
Registered: [name] - BORROW: Wyświetl komunikat o powodzeniu albo
Error: [exception message] - RETURN:
[userName] returned [bookTitle] - SEARCH_TITLE: Wyświetl
Search '[keyword]':, a następnie szczegóły każdej pasującej książki alboNo results - SEARCH_AUTHOR: Taki sam format jak w przypadku wyszukiwania według tytułu
- REMOVE_BOOK:
Removed: [isbn]alboCannot remove: [isbn]
Po przetworzeniu wszystkich poleceń wyświetl podsumowanie końcowe:
--- Final Status ---Books: [count]Users: [count]- Dla każdego użytkownika wyświetl
[name]: [borrowedCount] book(s)
Otrzymasz jedno wejście: ciąg poleceń rozdzielonych przecinkami.
Na przykład dla wejścia ADD_BOOK:ISBN-001:Clean Code:Robert Martin,ADD_BOOK:ISBN-002:Effective Java:Joshua Bloch,REGISTER_USER:U001:Alice,REGISTER_USER:U002:Bob,BORROW:U001:ISBN-001,BORROW:U002:ISBN-001,SEARCH_TITLE:java,RETURN:U001:ISBN-001,REMOVE_BOOK:ISBN-001 wynikiem będzie:
Added: Clean Code
Added: Effective Java
Registered: Alice
Registered: Bob
Alice borrowed Clean Code
Error: Book not available: ISBN-001
Search 'java':
[ISBN-002] Effective Java by Joshua Bloch
Alice returned Clean Code
Removed: ISBN-001
--- Final Status ---
Books: 1
Users: 2
Alice: 0 book(s)
Bob: 0 book(s)To ostatnie wyzwanie sprawdza, czy wszystkie Twoje komponenty, klasy, interfejsy, wyjątki i logika biblioteki działają razem bezproblemowo. Zbudowałeś kompletny, solidny system zarządzania biblioteką!
Spróbuj swoich sił
import java.util.Scanner;
import java.util.ArrayList;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Odczytaj polecenia oddzielone przecinkami
String input = scanner.nextLine();
String[] commands = input.split(",");
// Utwórz Library i AdminService
Library library = new Library();
AdminService adminService = new AdminService(library);
// Przetwórz każde polecenie
for (String command : commands) {
String[] parts = command.split(":");
String operation = parts[0];
if (operation.equals("ADD_BOOK")) {
String isbn = parts[1];
String title = parts[2];
String author = parts[3];
if (adminService.addBook(isbn, title, author)) {
System.out.println("Added: " + title);
}
} else if (operation.equals("REMOVE_BOOK")) {
String isbn = parts[1];
if (adminService.removeBook(isbn)) {
System.out.println("Removed: " + isbn);
} else {
System.out.println("Cannot remove: " + isbn);
}
} else if (operation.equals("REGISTER_USER")) {
String id = parts[1];
String name = parts[2];
if (adminService.registerUser(id, name)) {
System.out.println("Registered: " + name);
}
} else if (operation.equals("BORROW")) {
String userId = parts[1];
String isbn = parts[2];
try {
String result = library.borrowBook(userId, isbn);
System.out.println(result);
} catch (LibraryException e) {
System.out.println("Error: " + e.getMessage());
}
}
// TODO: Dodaj obsługę polecenia RETURN
// TODO: Dodaj obsługę polecenia SEARCH_TITLE
// TODO: Dodaj obsługę polecenia SEARCH_AUTHOR
}
// TODO: Wyświetl stan końcowy
// --- Final Status ---
// Książki: [count]
// Użytkownicy: [count]
// Dla każdego użytkownika: [name]: [borrowedCount] książek
System.out.println("Operations completed");
}
}
Wszystkie lekcje w sekcji Programowanie obiektowe
1Podstawy programowania obiektowego
Pliki zewnętrzneWprowadzenie do programowania obiektowegoKlasy a obiektySłowo kluczowe thisMetodyPola (atrybuty)Metoda konstruktoraPrzeciążanie konstruktoraPodsumowanie — prosty kalkulator4Dziedziczenie
Podstawy dziedziczenia (extends)Słowo kluczowe superPrzesłanianie metod (@Override)Łańcuch wywołań konstruktorówKlasa ObjectDziedziczenie jedno- i wielopoziomoweDlaczego Java nie obsługuje wielodziedziczenia klasPodsumowanie – hierarchia pracowników7Metody specjalne i klasa Object
Metoda toString()equals() i hashCode()Metoda clone()compareTo() i ComparableInterfejs ComparatorPodsumowanie — własne sortowanie10Obsługa wyjątków w programowaniu obiektowym
Hierarchia klas wyjątkówWłasne wyjątkiBłędy sprawdzane a niesprawdzaneWzorzec try-with-resourcesPodsumowanie – zweryfikowany użytkownik13Projekt: System zarządzania biblioteką
Przegląd projektu i projekt UMLKlasy książki i użytkownikaSystem wypożyczeńFunkcja wyszukiwaniaInterfejs administratoraIntegracja obsługi wyjątkówTestowanie i integracja2Modyfikatory dostępu i enkapsulacja
Przegląd poziomów dostępuMetody pobierające i ustawiająceUkrywanie informacjiSłowo kluczowe finalPodsumowanie — menedżer kont bankowych5Polimorfizm
Podstawy przeciążania metodPrzesłanianie metod (w czasie wykonywania)Rzutowanie w górę i w dółOperator instanceofKlasy i metody abstrakcyjnePowtórka — kalkulator figur8Zaawansowane koncepcje OOP
Kompozycja a dziedziczenieAgregacja a kompozycjaKlasy wewnętrzne, zagnieżdżone i anonimoweEnumy i metody enumówRekordy (Java 16+)Klasy zapieczętowane (Java 17+)11Wzorce projektowe — część 1
Wprowadzenie do wzorców projektowychWzorzec SingletonWzorzec FactoryWzorzec BuilderWzorzec ObserverWzorzec Strategy3Właściwości klas i składowe statyczne
Zmienne instancji a zmienne statyczneMetody statyczneBloki statyczneStałe (static final)Powtórka – Counter i Utility6Interfejsy i klasy abstrakcyjne
Wprowadzenie do interfejsówImplementowanie interfejsówImplementacja wielu interfejsówMetody domyślne i statyczne w interfejsieKlasy abstrakcyjne a interfejsyInterfejsy funkcyjnePodsumowanie — system płatnościPoćwicz samodzielnie: Kompilator Java online