Skip to the content.
package com.bookshop.solid.srp;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

import com.bookshop.domain.Book;
import com.bookshop.domain.Customer;
import java.math.BigDecimal;
import java.util.List;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

@DisplayName("SRP -- totals, formatting and storage each live in their own class")
class ReceiptSrpTest {

    private final Customer alice = new Customer("c-1", "Alice", "alice@example.com", 2);
    private final Receipt receipt = new Receipt(alice, List.of(
            new Book("978-0132350884", "Clean Code", "Robert C. Martin", new BigDecimal("32.50"))));

    @Test
    @DisplayName("the maths is testable without any formatting or storage in sight")
    void totalsTestedInIsolation() {
        assertEquals(new BigDecimal("32.50"), receipt.total());
    }

    @Test
    @DisplayName("formatting is a separate concern -- it consumes a receipt, never computes one")
    void printingIsSeparate() {
        String printed = new ReceiptPrinter().print(receipt);

        assertTrue(printed.contains("Clean Code  32.50"));
        assertTrue(printed.endsWith("TOTAL  32.50\n"));
    }

    @Test
    @DisplayName("storage is a separate concern -- swappable without touching maths or layout")
    void storageIsSeparate() {
        ReceiptRepository repository = new ReceiptRepository();

        repository.save(receipt);

        assertEquals(List.of(receipt), repository.findByCustomer("c-1"));
    }
}

Raw file