← Back to Home

Sprint Challenge

Challenge Overview

In this sprint challenge, you'll apply the core concepts from this sprint: dependency injection, test-driven development, and mocking to build a library service application. You'll demonstrate your ability to write loosely coupled, testable code using best practices.

Learning Objectives Tested

Implementation Tasks

  1. Create interfaces for your dependencies to enable loose coupling
  2. Implement the library service with proper dependency injection
  3. Write comprehensive unit tests using mocks where appropriate
  4. Implement the required business logic following TDD practices
  5. Ensure your code follows best practices for maintainability

Code Example

// Example of a properly designed service with dependency injection
public class LibraryService {
    private final BookRepository bookRepository;
    private final UserRepository userRepository;
    private final NotificationService notificationService;
    
    public LibraryService(BookRepository bookRepository, 
                         UserRepository userRepository,
                         NotificationService notificationService) {
        this.bookRepository = bookRepository;
        this.userRepository = userRepository;
        this.notificationService = notificationService;
    }
    
    public boolean borrowBook(String userId, String bookId) {
        User user = userRepository.findById(userId);
        Book book = bookRepository.findById(bookId);
        
        if (user == null || book == null || !book.isAvailable()) {
            return false;
        }
        
        book.setAvailable(false);
        book.setBorrowedBy(userId);
        
        bookRepository.save(book);
        notificationService.sendBookBorrowedNotification(user.getEmail(), book.getTitle());
        
        return true;
    }
}

// Example of a proper test with mocks
@Test
void shouldBorrowAvailableBook() {
    // Arrange
    String userId = "user123";
    String bookId = "book456";
    
    User testUser = new User(userId, "test@example.com");
    Book testBook = new Book(bookId, "Test Book", true);
    
    BookRepository mockBookRepo = mock(BookRepository.class);
    UserRepository mockUserRepo = mock(UserRepository.class);
    NotificationService mockNotification = mock(NotificationService.class);
    
    when(mockUserRepo.findById(userId)).thenReturn(testUser);
    when(mockBookRepo.findById(bookId)).thenReturn(testBook);
    
    LibraryService service = new LibraryService(mockBookRepo, mockUserRepo, mockNotification);
    
    // Act
    boolean result = service.borrowBook(userId, bookId);
    
    // Assert
    assertTrue(result);
    assertFalse(testBook.isAvailable());
    assertEquals(userId, testBook.getBorrowedBy());
    
    verify(mockBookRepo).save(testBook);
    verify(mockNotification).sendBookBorrowedNotification(testUser.getEmail(), testBook.getTitle());
}

Setup Instructions

  1. Fork and clone the Sprint 12 Challenge Starter Repository
  2. Follow the README instructions to set up your project
  3. Complete all project tasks
  4. Submit your work through the Portal

Resources