Menu
Coddy logo textTech

Testy jednostkowe (NUnit/xUnit)

Część sekcji Programowanie obiektowe ścieżki C# w Coddy. Lekcja 67 z 70.

challenge icon

Wyzwanie

Łatwy

Dokończmy Twój projekt systemu bibliotecznego, dodając testy jednostkowe! Testowanie jest niezbędne, aby upewnić się, że Twój kod działa poprawnie i nadal działa podczas wprowadzania zmian. Utworzysz osobny plik testowy, który sprawdzi podstawowe funkcje Twojego systemu bibliotecznego.

Będziesz dalej pracować z istniejącą strukturą projektu, dodając nowy plik testowy:

  • Book.cs: Zachowaj swoją klasę Book z właściwościami Id, Title, Author, IsAvailable oraz metodami Borrow() i Return().
  • User.cs: Zachowaj swoją klasę User ze śledzeniem wypożyczeń, stałą MaxBooks, metodą CanBorrow() i metodami do zarządzania wypożyczonymi książkami.
  • Library.cs: Zachowaj swoją klasę Library z logiką wypożyczania, metodami wyszukiwania oraz metodami GetAllBooks() i GetAllUsers().
  • LibraryTests.cs: To Twój nowy plik testowy! Utwórz klasę testową, która sprawdzi, czy Twój system biblioteczny działa poprawnie. Napiszesz metody testowe, które sprawdzą różne scenariusze i określą, czy każdy test zakończył się powodzeniem, czy niepowodzeniem.
  • Program.cs: Punkt wejścia, który uruchamia testy i wyświetla wyniki.

Twoja klasa testowa powinna zawierać metody sprawdzające następujące scenariusze:

  • TestBookBorrow - Sprawdź, czy wypożyczenie dostępnej książki się powiedzie i zmieni jej dostępność
  • TestBookBorrowUnavailable - Sprawdź, czy próba wypożyczenia już wypożyczonej książki odpowiednio się nie powiedzie
  • TestUserBorrowingLimit - Sprawdź, czy użytkownicy nie mogą wypożyczyć więcej niż 3 książek
  • TestBookReturn - Sprawdź, czy zwrócenie wypożyczonej książki działa poprawnie
  • TestSearchByAuthor - Sprawdź, czy wyszukiwanie według autora zwraca właściwe książki

Każda metoda testowa powinna zwracać wartość logiczną wskazującą, czy test się powiódł. Utwórz prosty moduł uruchamiający testy, który wykona wszystkie testy i wyświetli wyniki.

Otrzymasz następujące dane wejściowe:

  • Liczba scenariuszy testowych do uruchomienia (1-5, odpowiadających testom wymienionym powyżej)

Dla każdego uruchomionego testu wyświetl wynik w formacie:

{TestName}: {PASS|FAIL}

Po zakończeniu wszystkich testów wyświetl podsumowanie:

--- Test Summary ---
Passed: {count}
Failed: {count}
Total: {count}

Na przykład, jeśli dane wejściowe to:

3

Wynik powinien wyglądać następująco:

TestBookBorrow: PASS
TestBookBorrowUnavailable: PASS
TestUserBorrowingLimit: PASS
--- Test Summary ---
Passed: 3
Failed: 0
Total: 3

Inny przykład, obejmujący wszystkie 5 testów:

5

Wynik powinien wyglądać następująco:

TestBookBorrow: PASS
TestBookBorrowUnavailable: PASS
TestUserBorrowingLimit: PASS
TestBookReturn: PASS
TestSearchByAuthor: PASS
--- Test Summary ---
Passed: 5
Failed: 0
Total: 5

Testy powinny tworzyć nowe instancje Book, User i Library dla każdego testu, aby zapewnić izolację. Dzięki temu stan jednego testu nie wpłynie na inny. Potraktuj każdy test jako samodzielne sprawdzenie konkretnego zachowania Twojego systemu!

Spróbuj swoich sił

using System;
using System.Collections.Generic;

namespace LibrarySystem
{
    class Program
    {
        public static void Main(string[] args)
        {
            // Read library name
            string libraryName = Console.ReadLine();
            
            // Create a Library instance with the library name
            Library library = new Library(libraryName);
            
            // Read number of commands
            int numCommands = Convert.ToInt32(Console.ReadLine());
            
            // Process commands
            for (int i = 0; i < numCommands; i++)
            {
                string commandLine = Console.ReadLine();
                string[] parts = commandLine.Split('|');
                string command = parts[0];
                
                if (command == "ADD_BOOK")
                {
                    string bookId = parts[1];
                    string bookTitle = parts[2];
                    string bookAuthor = parts[3];
                    
                    Book book = new Book(bookId, bookTitle, bookAuthor);
                    library.AddBook(book);
                    Console.WriteLine($"Added: {bookTitle}");
                }
                else if (command == "ADD_USER")
                {
                    string userName = parts[1];
                    int memberId = Convert.ToInt32(parts[2]);
                    
                    User user = new User(userName, memberId);
                    library.RegisterUser(user);
                    Console.WriteLine($"Registered: {userName}");
                }
                else if (command == "BORROW")
                {
                    string bookId = parts[1];
                    int memberId = Convert.ToInt32(parts[2]);
                    
                    string result = library.BorrowBook(bookId, memberId);
                    Console.WriteLine(result);
                }
                else if (command == "RETURN")
                {
                    string bookId = parts[1];
                    int memberId = Convert.ToInt32(parts[2]);
                    
                    string result = library.ReturnBook(bookId, memberId);
                    Console.WriteLine(result);
                }
                else if (command == "SEARCH")
                {
                    string searchType = parts[1];
                    List<Book> results = new List<Book>();
                    
                    if (searchType == "title")
                    {
                        string searchValue = parts[2];
                        results = library.SearchByTitle(searchValue);
                    }
                    else if (searchType == "author")
                    {
                        string searchValue = parts[2];
                        results = library.GetBooksByAuthor(searchValue);
                    }
                    else if (searchType == "available")
                    {
                        results = library.GetAvailableBooks();
                    }
                    else if (searchType == "borrowed")
                    {
                        results = library.GetBorrowedBooks();
                    }
                    
                    if (results.Count == 0)
                    {
                        Console.WriteLine("No books found");
                    }
                    else
                    {
                        foreach (Book book in results)
                        {
                            Console.WriteLine($"{book.Title} by {book.Author}");
                        }
                    }
                }
                else if (command == "STATUS")
                {
                    List<Book> allBooks = library.GetAllBooks();
                    List<Book> availableBooks = library.GetAvailableBooks();
                    List<User> allUsers = library.GetAllUsers();
                    List<Book> borrowedBooks = library.GetBorrowedBooks();
                    
                    Console.WriteLine("--- Library Status ---");
                    Console.WriteLine($"Total Books: {allBooks.Count}");
                    Console.WriteLine($"Available: {availableBooks.Count}");
                    Console.WriteLine($"Total Users: {allUsers.Count}");
                    Console.WriteLine($"Books Borrowed: {borrowedBooks.Count}");
                }
            }
        }
    }
}

Wszystkie lekcje w sekcji Programowanie obiektowe

Poćwicz samodzielnie: Kompilator C# online