Menu
CoddyTech

Unit Testing (NUnit/xUnit)

Part of the Object Oriented Programming section of Coddy's C# journey. Lesson 67 of 70.

challenge icon

Challenge

Easy

Let's complete your Library System project by adding unit tests! Testing is essential for ensuring your code works correctly and continues to work as you make changes. You'll create a dedicated test file that verifies the core functionality of your library system.

You'll continue working with your existing project structure, adding a new test file:

  • Book.cs: Keep your Book class with Id, Title, Author, IsAvailable, and the Borrow() and Return() methods.
  • User.cs: Keep your User class with borrowing tracking, MaxBooks constant, CanBorrow(), and methods for managing borrowed books.
  • Library.cs: Keep your Library class with borrowing logic, search methods, and the GetAllBooks() and GetAllUsers() methods.
  • LibraryTests.cs: This is your new test file! Create a test class that verifies your library system works correctly. You'll write test methods that check various scenarios and report whether each test passes or fails.
  • Program.cs: Your entry point that runs the tests and displays results.

Your test class should include methods that test these scenarios:

  • TestBookBorrow - Verify that borrowing an available book succeeds and changes its availability
  • TestBookBorrowUnavailable - Verify that borrowing an already-borrowed book fails appropriately
  • TestUserBorrowingLimit - Verify that users cannot borrow more than 3 books
  • TestBookReturn - Verify that returning a borrowed book works correctly
  • TestSearchByAuthor - Verify that searching by author returns the correct books

Each test method should return a boolean indicating whether the test passed. Create a simple test runner that executes all tests and prints the results.

You will receive the following inputs:

  • Number of test scenarios to run (1-5, corresponding to the tests listed above)

For each test that runs, print the result in the format:

{TestName}: {PASS|FAIL}

After all tests complete, print a summary:

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

For example, if the input is:

3

The output should be:

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

Another example with all 5 tests:

5

The output should be:

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

Your tests should create fresh instances of Book, User, and Library for each test to ensure isolation. This way, one test's state doesn't affect another. Think of each test as a self-contained verification of a specific behavior in your system!

Try it yourself

using System;

namespace LibrarySystem
{
    class Program
    {
        public static void Main(string[] args)
        {
            // Read the number of tests to run
            int numTests = Convert.ToInt32(Console.ReadLine());

            // TODO: Create a LibraryTests object and run the first numTests tests
        }
    }
}

All lessons in Object Oriented Programming

Practice on your own: Online C# compiler