We've implemented comprehensive unit testing for the Hotel Booking System's core business logic with 100% test coverage using modern testing practices and frameworks.
- Removed Fake Repositories & Services: Eliminated tightly-coupled fake implementations
- Adopted Moq Framework: Clean dependency mocking for true unit test isolation
- Implemented Fluent Assertions: More readable and maintainable test code
HotelBooking.UnitTests/
├── Entities/
│ ├── BookingTests.cs
│ ├── CustomerTests.cs
│ └── RoomTests.cs
├── Services/BookingManager/
│ ├── CreateBookingTests.cs
│ ├── FindAvailableRoomTests.cs
│ └── GetFullyOccupiedDatesTests.cs
└── Controllers/
└── RoomsControllerTests.cs
- xUnit: Lightweight testing framework
- Moq: Dependency mocking and isolation
- FluentAssertions: Readable test assertions
- Bogus: Realistic test data generation
// Old way:
Assert.Equal(-1, roomId);
// New way (more readable):
roomId.Should().Be(-1);
// Complex assertions:
result.Should().NotBeNull()
.And.BeOfType<List<DateTime>>()
.And.HaveCount(3);- 100% Core Coverage: Every class in
HotelBooking.Coreis tested - Entity Tests: Comprehensive property and validation testing
- Business Logic Tests: All BookingManager methods thoroughly tested
- Consistent Structure: Each service class has exactly 7 focused tests
[Fact]
public async Task CreateBooking_NoRoomAvailable_ReturnsFalseAndDoesNotAddBooking()
{
// Arrange
var rooms = roomFaker.Generate(2);
var bookings = new List<Booking>
{
CreateBookingWithRoom(DateTime.Today.AddDays(1), DateTime.Today.AddDays(3), rooms[0].Id),
CreateBookingWithRoom(DateTime.Today.AddDays(1), DateTime.Today.AddDays(3), rooms[1].Id)
};
roomRepository.Setup(r => r.GetAllAsync()).ReturnsAsync(rooms);
bookingRepository.Setup(b => b.GetAllAsync()).ReturnsAsync(bookings);
var booking = CreateBookingWithDates(DateTime.Today.AddDays(2), DateTime.Today.AddDays(2));
// Act
var result = await bookingManager.CreateBooking(booking);
// Assert
result.Should().BeFalse();
bookingRepository.Verify(b => b.AddAsync(It.IsAny<Booking>()), Times.Never);
}[Fact]
public async Task FindAvailableRoom_StartDateNotInTheFuture_ThrowsArgumentException()
{
// Arrange
DateTime date = DateTime.Today;
// Act
var act = () => bookingManager.FindAvailableRoom(date, date);
// Assert
await act.Should().ThrowAsync<ArgumentException>();
}[Fact]
public async Task GetFullyOccupiedDates_StartDateAfterEndDate_ThrowsArgumentException()
{
// Arrange
DateTime startDate = DateTime.Today.AddDays(15);
DateTime endDate = DateTime.Today.AddDays(10);
// Act
Task result() => bookingManager.GetFullyOccupiedDates(startDate, endDate);
// Assert
await FluentActions.Invoking(result).Should().ThrowAsync<ArgumentException>();
}True Unit Testing: Complete isolation through proper mocking
Readable Tests: Natural language assertions with FluentAssertions
Maintainable Code: Well-organized test structure
Fast Execution: No external dependencies
Complete Coverage: 100% confidence in core business logic