package com.bookshop.solid.dip;
import static org.junit.jupiter.api.Assertions.assertEquals;
import com.bookshop.domain.Book;
import com.bookshop.domain.Customer;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
@DisplayName("DIP -- business logic tested with fakes because it depends on abstractions")
class OrderServiceDipTest {
private final Customer alice = new Customer("c-1", "Alice", "alice@example.com", 2);
private final List<Book> basket = List.of(
new Book("978-0132350884", "Clean Code", "Robert C. Martin", new BigDecimal("32.50")));
@Test
@DisplayName("the service runs against a fake gateway -- no credentials, no network, no mocks")
void serviceIsTestableWithFakes() {
List<String> chargeLog = new ArrayList<>();
PaymentGateway fakeGateway = (customer, amount) -> {
chargeLog.add(customer.id() + ":" + amount);
return "fake-ref-1";
};
OrderService service = new OrderService(fakeGateway, new InMemoryOrderRepository());
PlacedOrder order = service.placeOrder(alice, basket);
assertEquals("fake-ref-1", order.paymentRef());
assertEquals(List.of("c-1:32.50"), chargeLog);
}
@Test
@DisplayName("infrastructure is swappable -- the same service works with any repository")
void infrastructureIsSwappable() {
OrderRepository repository = new InMemoryOrderRepository();
OrderService service = new OrderService((customer, amount) -> "ref", repository);
service.placeOrder(alice, basket);
assertEquals(1, repository.forCustomer("c-1").size());
assertEquals(new BigDecimal("32.50"), repository.forCustomer("c-1").get(0).total());
}
}