mirror of
https://github.com/tiennm99/java-design-patterns.git
synced 2026-09-03 08:18:55 +00:00
deps: Refactor dependencies (#3224)
* remove spring dep move junit, logging, mockito under dep mgmt * upgrade anti-corruption-layer deps * async method invocation * balking, bloc * bridge to bytecode * caching * callback - cqrs * component - health check * hexagonal - metadata mapping * rest of the patterns * remove checkstyle, take spotless into use
This commit is contained in:
@@ -34,6 +34,14 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>domain-model</artifactId>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
|
||||
@@ -32,7 +32,6 @@ import javax.sql.DataSource;
|
||||
import org.h2.jdbcx.JdbcDataSource;
|
||||
import org.joda.money.Money;
|
||||
|
||||
|
||||
/**
|
||||
* Domain Model pattern is a more complex solution for organizing domain logic than Transaction
|
||||
* Script and Table Module. It provides an object-oriented way of dealing with complicated logic.
|
||||
@@ -42,10 +41,10 @@ import org.joda.money.Money;
|
||||
* is that in Table Module a single class encapsulates all the domain logic for all records stored
|
||||
* in table when in Domain Model every single class represents only one record in underlying table.
|
||||
*
|
||||
* <p>In this example, we will use the Domain Model pattern to implement buying of products
|
||||
* by customers in a Shop. The main method will create a customer and a few products.
|
||||
* Customer will do a few purchases, try to buy product which are too expensive for him,
|
||||
* return product which he bought to return money.</p>
|
||||
* <p>In this example, we will use the Domain Model pattern to implement buying of products by
|
||||
* customers in a Shop. The main method will create a customer and a few products. Customer will do
|
||||
* a few purchases, try to buy product which are too expensive for him, return product which he
|
||||
* bought to return money.
|
||||
*/
|
||||
public class App {
|
||||
|
||||
@@ -80,11 +79,7 @@ public class App {
|
||||
var customerDao = new CustomerDaoImpl(dataSource);
|
||||
|
||||
var tom =
|
||||
Customer.builder()
|
||||
.name("Tom")
|
||||
.money(Money.of(USD, 30))
|
||||
.customerDao(customerDao)
|
||||
.build();
|
||||
Customer.builder().name("Tom").money(Money.of(USD, 30)).customerDao(customerDao).build();
|
||||
|
||||
tom.save();
|
||||
|
||||
|
||||
@@ -36,9 +36,8 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import org.joda.money.Money;
|
||||
|
||||
/**
|
||||
* This class organizes domain logic of customer.
|
||||
* A single instance of this class
|
||||
* contains both the data and behavior of a single customer.
|
||||
* This class organizes domain logic of customer. A single instance of this class contains both the
|
||||
* data and behavior of a single customer.
|
||||
*/
|
||||
@Slf4j
|
||||
@Getter
|
||||
@@ -51,9 +50,7 @@ public class Customer {
|
||||
@NonNull private String name;
|
||||
@NonNull private Money money;
|
||||
|
||||
/**
|
||||
* Save customer or update if customer already exist.
|
||||
*/
|
||||
/** Save customer or update if customer already exist. */
|
||||
public void save() {
|
||||
try {
|
||||
Optional<Customer> customer = customerDao.findByName(name);
|
||||
@@ -117,9 +114,7 @@ public class Customer {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Print customer's purchases.
|
||||
*/
|
||||
/** Print customer's purchases. */
|
||||
public void showPurchases() {
|
||||
Optional<String> purchasesToShow =
|
||||
purchases.stream()
|
||||
@@ -133,9 +128,7 @@ public class Customer {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Print customer's money balance.
|
||||
*/
|
||||
/** Print customer's money balance. */
|
||||
public void showBalance() {
|
||||
LOGGER.info(name + " balance: " + money);
|
||||
}
|
||||
|
||||
@@ -27,9 +27,7 @@ package com.iluwatar.domainmodel;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* DAO interface for customer transactions.
|
||||
*/
|
||||
/** DAO interface for customer transactions. */
|
||||
public interface CustomerDao {
|
||||
|
||||
Optional<Customer> findByName(String name) throws SQLException;
|
||||
|
||||
@@ -32,9 +32,7 @@ import java.util.Optional;
|
||||
import javax.sql.DataSource;
|
||||
import org.joda.money.Money;
|
||||
|
||||
/**
|
||||
* Implementations for database operations of Customer.
|
||||
*/
|
||||
/** Implementations for database operations of Customer. */
|
||||
public class CustomerDaoImpl implements CustomerDao {
|
||||
|
||||
private final DataSource dataSource;
|
||||
|
||||
@@ -40,9 +40,8 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import org.joda.money.Money;
|
||||
|
||||
/**
|
||||
* This class organizes domain logic of product.
|
||||
* A single instance of this class
|
||||
* contains both the data and behavior of a single product.
|
||||
* This class organizes domain logic of product. A single instance of this class contains both the
|
||||
* data and behavior of a single product.
|
||||
*/
|
||||
@Slf4j
|
||||
@Getter
|
||||
@@ -59,9 +58,7 @@ public class Product {
|
||||
@NonNull private Money price;
|
||||
@NonNull private LocalDate expirationDate;
|
||||
|
||||
/**
|
||||
* Save product or update if product already exist.
|
||||
*/
|
||||
/** Save product or update if product already exist. */
|
||||
public void save() {
|
||||
try {
|
||||
Optional<Product> product = productDao.findByName(name);
|
||||
@@ -75,16 +72,14 @@ public class Product {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate sale price of product with discount.
|
||||
*/
|
||||
/** Calculate sale price of product with discount. */
|
||||
public Money getSalePrice() {
|
||||
return price.minus(calculateDiscount());
|
||||
}
|
||||
|
||||
private Money calculateDiscount() {
|
||||
if (ChronoUnit.DAYS.between(LocalDate.now(), expirationDate)
|
||||
< DAYS_UNTIL_EXPIRATION_WHEN_DISCOUNT_ACTIVE) {
|
||||
< DAYS_UNTIL_EXPIRATION_WHEN_DISCOUNT_ACTIVE) {
|
||||
|
||||
return price.multipliedBy(DISCOUNT_RATE, RoundingMode.DOWN);
|
||||
}
|
||||
|
||||
@@ -27,9 +27,7 @@ package com.iluwatar.domainmodel;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* DAO interface for product transactions.
|
||||
*/
|
||||
/** DAO interface for product transactions. */
|
||||
public interface ProductDao {
|
||||
|
||||
Optional<Product> findByName(String name) throws SQLException;
|
||||
|
||||
@@ -33,9 +33,7 @@ import java.util.Optional;
|
||||
import javax.sql.DataSource;
|
||||
import org.joda.money.Money;
|
||||
|
||||
/**
|
||||
* Implementations for database transactions of Product.
|
||||
*/
|
||||
/** Implementations for database transactions of Product. */
|
||||
public class ProductDaoImpl implements ProductDao {
|
||||
|
||||
private final DataSource dataSource;
|
||||
|
||||
@@ -24,10 +24,10 @@
|
||||
*/
|
||||
package com.iluwatar.domainmodel;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/** Tests that Domain Model example runs without errors. */
|
||||
final class AppTest {
|
||||
|
||||
@@ -35,5 +35,4 @@ final class AppTest {
|
||||
void shouldExecuteApplicationWithoutException() {
|
||||
assertDoesNotThrow(() -> App.main(new String[] {}));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -24,18 +24,18 @@
|
||||
*/
|
||||
package com.iluwatar.domainmodel;
|
||||
|
||||
import static org.joda.money.CurrencyUnit.USD;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.time.LocalDate;
|
||||
import javax.sql.DataSource;
|
||||
import org.joda.money.CurrencyUnit;
|
||||
import org.joda.money.Money;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import javax.sql.DataSource;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.time.LocalDate;
|
||||
|
||||
import static org.joda.money.CurrencyUnit.USD;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class CustomerDaoImplTest {
|
||||
|
||||
@@ -62,7 +62,12 @@ class CustomerDaoImplTest {
|
||||
// setup objects
|
||||
customerDao = new CustomerDaoImpl(dataSource);
|
||||
|
||||
customer = Customer.builder().name("customer").money(Money.of(CurrencyUnit.USD,100.0)).customerDao(customerDao).build();
|
||||
customer =
|
||||
Customer.builder()
|
||||
.name("customer")
|
||||
.money(Money.of(CurrencyUnit.USD, 100.0))
|
||||
.customerDao(customerDao)
|
||||
.build();
|
||||
|
||||
product =
|
||||
Product.builder()
|
||||
|
||||
@@ -24,89 +24,90 @@
|
||||
*/
|
||||
package com.iluwatar.domainmodel;
|
||||
|
||||
import org.joda.money.CurrencyUnit;
|
||||
import org.joda.money.Money;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.joda.money.CurrencyUnit.USD;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.time.LocalDate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Optional;
|
||||
|
||||
import static org.joda.money.CurrencyUnit.USD;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.mockito.Mockito.*;
|
||||
import org.joda.money.CurrencyUnit;
|
||||
import org.joda.money.Money;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class CustomerTest {
|
||||
|
||||
private CustomerDao customerDao;
|
||||
private Customer customer;
|
||||
private Product product;
|
||||
private CustomerDao customerDao;
|
||||
private Customer customer;
|
||||
private Product product;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
customerDao = mock(CustomerDao.class);
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
customerDao = mock(CustomerDao.class);
|
||||
|
||||
customer = Customer.builder()
|
||||
.name("customer")
|
||||
.money(Money.of(CurrencyUnit.USD, 100.0))
|
||||
.customerDao(customerDao)
|
||||
.build();
|
||||
customer =
|
||||
Customer.builder()
|
||||
.name("customer")
|
||||
.money(Money.of(CurrencyUnit.USD, 100.0))
|
||||
.customerDao(customerDao)
|
||||
.build();
|
||||
|
||||
product = Product.builder()
|
||||
.name("product")
|
||||
.price(Money.of(USD, 100.0))
|
||||
.expirationDate(LocalDate.now().plusDays(10))
|
||||
.productDao(mock(ProductDao.class))
|
||||
.build();
|
||||
}
|
||||
product =
|
||||
Product.builder()
|
||||
.name("product")
|
||||
.price(Money.of(USD, 100.0))
|
||||
.expirationDate(LocalDate.now().plusDays(10))
|
||||
.productDao(mock(ProductDao.class))
|
||||
.build();
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldSaveCustomer() throws SQLException {
|
||||
when(customerDao.findByName("customer")).thenReturn(Optional.empty());
|
||||
@Test
|
||||
void shouldSaveCustomer() throws SQLException {
|
||||
when(customerDao.findByName("customer")).thenReturn(Optional.empty());
|
||||
|
||||
customer.save();
|
||||
customer.save();
|
||||
|
||||
verify(customerDao, times(1)).save(customer);
|
||||
verify(customerDao, times(1)).save(customer);
|
||||
|
||||
when(customerDao.findByName("customer")).thenReturn(Optional.of(customer));
|
||||
when(customerDao.findByName("customer")).thenReturn(Optional.of(customer));
|
||||
|
||||
customer.save();
|
||||
customer.save();
|
||||
|
||||
verify(customerDao, times(1)).update(customer);
|
||||
}
|
||||
verify(customerDao, times(1)).update(customer);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldAddProductToPurchases() {
|
||||
product.setPrice(Money.of(USD, 200.0));
|
||||
@Test
|
||||
void shouldAddProductToPurchases() {
|
||||
product.setPrice(Money.of(USD, 200.0));
|
||||
|
||||
customer.buyProduct(product);
|
||||
customer.buyProduct(product);
|
||||
|
||||
assertEquals(customer.getPurchases(), new ArrayList<>());
|
||||
assertEquals(customer.getMoney(), Money.of(USD,100));
|
||||
assertEquals(customer.getPurchases(), new ArrayList<>());
|
||||
assertEquals(customer.getMoney(), Money.of(USD, 100));
|
||||
|
||||
product.setPrice(Money.of(USD, 100.0));
|
||||
product.setPrice(Money.of(USD, 100.0));
|
||||
|
||||
customer.buyProduct(product);
|
||||
customer.buyProduct(product);
|
||||
|
||||
assertEquals(new ArrayList<>(Arrays.asList(product)), customer.getPurchases());
|
||||
assertEquals(Money.zero(USD), customer.getMoney());
|
||||
}
|
||||
assertEquals(new ArrayList<>(Arrays.asList(product)), customer.getPurchases());
|
||||
assertEquals(Money.zero(USD), customer.getMoney());
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldRemoveProductFromPurchases() {
|
||||
customer.setPurchases(new ArrayList<>(Arrays.asList(product)));
|
||||
@Test
|
||||
void shouldRemoveProductFromPurchases() {
|
||||
customer.setPurchases(new ArrayList<>(Arrays.asList(product)));
|
||||
|
||||
customer.returnProduct(product);
|
||||
customer.returnProduct(product);
|
||||
|
||||
assertEquals(new ArrayList<>(), customer.getPurchases());
|
||||
assertEquals(Money.of(USD, 200), customer.getMoney());
|
||||
assertEquals(new ArrayList<>(), customer.getPurchases());
|
||||
assertEquals(Money.of(USD, 200), customer.getMoney());
|
||||
|
||||
customer.returnProduct(product);
|
||||
customer.returnProduct(product);
|
||||
|
||||
assertEquals(new ArrayList<>(), customer.getPurchases());
|
||||
assertEquals(Money.of(USD, 200), customer.getMoney());
|
||||
}
|
||||
assertEquals(new ArrayList<>(), customer.getPurchases());
|
||||
assertEquals(Money.of(USD, 200), customer.getMoney());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,104 +24,104 @@
|
||||
*/
|
||||
package com.iluwatar.domainmodel;
|
||||
|
||||
import static org.joda.money.CurrencyUnit.USD;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.time.LocalDate;
|
||||
import javax.sql.DataSource;
|
||||
import org.joda.money.Money;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import javax.sql.DataSource;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.time.LocalDate;
|
||||
|
||||
import static org.joda.money.CurrencyUnit.USD;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class ProductDaoImplTest {
|
||||
|
||||
public static final String INSERT_PRODUCT_SQL =
|
||||
"insert into PRODUCTS values('product', 100, DATE '2021-06-27')";
|
||||
public static final String SELECT_PRODUCTS_SQL =
|
||||
"select name, price, expiration_date from PRODUCTS";
|
||||
public static final String INSERT_PRODUCT_SQL =
|
||||
"insert into PRODUCTS values('product', 100, DATE '2021-06-27')";
|
||||
public static final String SELECT_PRODUCTS_SQL =
|
||||
"select name, price, expiration_date from PRODUCTS";
|
||||
|
||||
private DataSource dataSource;
|
||||
private ProductDao productDao;
|
||||
private Product product;
|
||||
private DataSource dataSource;
|
||||
private ProductDao productDao;
|
||||
private Product product;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() throws SQLException {
|
||||
// create schema
|
||||
dataSource = TestUtils.createDataSource();
|
||||
@BeforeEach
|
||||
void setUp() throws SQLException {
|
||||
// create schema
|
||||
dataSource = TestUtils.createDataSource();
|
||||
|
||||
TestUtils.deleteSchema(dataSource);
|
||||
TestUtils.createSchema(dataSource);
|
||||
TestUtils.deleteSchema(dataSource);
|
||||
TestUtils.createSchema(dataSource);
|
||||
|
||||
// setup objects
|
||||
productDao = new ProductDaoImpl(dataSource);
|
||||
// setup objects
|
||||
productDao = new ProductDaoImpl(dataSource);
|
||||
|
||||
product =
|
||||
Product.builder()
|
||||
.name("product")
|
||||
.price(Money.of(USD, 100.0))
|
||||
.expirationDate(LocalDate.parse("2021-06-27"))
|
||||
.productDao(productDao)
|
||||
.build();
|
||||
product =
|
||||
Product.builder()
|
||||
.name("product")
|
||||
.price(Money.of(USD, 100.0))
|
||||
.expirationDate(LocalDate.parse("2021-06-27"))
|
||||
.productDao(productDao)
|
||||
.build();
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void tearDown() throws SQLException {
|
||||
TestUtils.deleteSchema(dataSource);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldFindProductByName() throws SQLException {
|
||||
var product = productDao.findByName("product");
|
||||
|
||||
assertTrue(product.isEmpty());
|
||||
|
||||
TestUtils.executeSQL(INSERT_PRODUCT_SQL, dataSource);
|
||||
|
||||
product = productDao.findByName("product");
|
||||
|
||||
assertTrue(product.isPresent());
|
||||
assertEquals("product", product.get().getName());
|
||||
assertEquals(Money.of(USD, 100), product.get().getPrice());
|
||||
assertEquals(LocalDate.parse("2021-06-27"), product.get().getExpirationDate());
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldSaveProduct() throws SQLException {
|
||||
|
||||
productDao.save(product);
|
||||
|
||||
try (var connection = dataSource.getConnection();
|
||||
var statement = connection.createStatement();
|
||||
ResultSet rs = statement.executeQuery(SELECT_PRODUCTS_SQL)) {
|
||||
|
||||
assertTrue(rs.next());
|
||||
assertEquals(product.getName(), rs.getString("name"));
|
||||
assertEquals(product.getPrice(), Money.of(USD, rs.getBigDecimal("price")));
|
||||
assertEquals(product.getExpirationDate(), rs.getDate("expiration_date").toLocalDate());
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void tearDown() throws SQLException {
|
||||
TestUtils.deleteSchema(dataSource);
|
||||
}
|
||||
assertThrows(SQLException.class, () -> productDao.save(product));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldFindProductByName() throws SQLException {
|
||||
var product = productDao.findByName("product");
|
||||
@Test
|
||||
void shouldUpdateProduct() throws SQLException {
|
||||
TestUtils.executeSQL(INSERT_PRODUCT_SQL, dataSource);
|
||||
|
||||
assertTrue(product.isEmpty());
|
||||
product.setPrice(Money.of(USD, 99.0));
|
||||
|
||||
TestUtils.executeSQL(INSERT_PRODUCT_SQL, dataSource);
|
||||
productDao.update(product);
|
||||
|
||||
product = productDao.findByName("product");
|
||||
try (var connection = dataSource.getConnection();
|
||||
var statement = connection.createStatement();
|
||||
ResultSet rs = statement.executeQuery(SELECT_PRODUCTS_SQL)) {
|
||||
|
||||
assertTrue(product.isPresent());
|
||||
assertEquals("product", product.get().getName());
|
||||
assertEquals(Money.of(USD, 100), product.get().getPrice());
|
||||
assertEquals(LocalDate.parse("2021-06-27"), product.get().getExpirationDate());
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldSaveProduct() throws SQLException {
|
||||
|
||||
productDao.save(product);
|
||||
|
||||
try (var connection = dataSource.getConnection();
|
||||
var statement = connection.createStatement();
|
||||
ResultSet rs = statement.executeQuery(SELECT_PRODUCTS_SQL)) {
|
||||
|
||||
assertTrue(rs.next());
|
||||
assertEquals(product.getName(), rs.getString("name"));
|
||||
assertEquals(product.getPrice(), Money.of(USD, rs.getBigDecimal("price")));
|
||||
assertEquals(product.getExpirationDate(), rs.getDate("expiration_date").toLocalDate());
|
||||
}
|
||||
|
||||
assertThrows(SQLException.class, () -> productDao.save(product));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldUpdateProduct() throws SQLException {
|
||||
TestUtils.executeSQL(INSERT_PRODUCT_SQL, dataSource);
|
||||
|
||||
product.setPrice(Money.of(USD, 99.0));
|
||||
|
||||
productDao.update(product);
|
||||
|
||||
try (var connection = dataSource.getConnection();
|
||||
var statement = connection.createStatement();
|
||||
ResultSet rs = statement.executeQuery(SELECT_PRODUCTS_SQL)) {
|
||||
|
||||
assertTrue(rs.next());
|
||||
assertEquals(product.getName(), rs.getString("name"));
|
||||
assertEquals(product.getPrice(), Money.of(USD, rs.getBigDecimal("price")));
|
||||
assertEquals(product.getExpirationDate(), rs.getDate("expiration_date").toLocalDate());
|
||||
}
|
||||
assertTrue(rs.next());
|
||||
assertEquals(product.getName(), rs.getString("name"));
|
||||
assertEquals(product.getPrice(), Money.of(USD, rs.getBigDecimal("price")));
|
||||
assertEquals(product.getExpirationDate(), rs.getDate("expiration_date").toLocalDate());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,55 +24,56 @@
|
||||
*/
|
||||
package com.iluwatar.domainmodel;
|
||||
|
||||
import org.joda.money.Money;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import java.sql.SQLException;
|
||||
import java.time.LocalDate;
|
||||
import java.util.Optional;
|
||||
|
||||
import static org.joda.money.CurrencyUnit.USD;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.time.LocalDate;
|
||||
import java.util.Optional;
|
||||
import org.joda.money.Money;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class ProductTest {
|
||||
|
||||
private ProductDao productDao;
|
||||
private Product product;
|
||||
private ProductDao productDao;
|
||||
private Product product;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
productDao = mock(ProductDaoImpl.class);
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
productDao = mock(ProductDaoImpl.class);
|
||||
|
||||
product = Product.builder()
|
||||
.name("product")
|
||||
.price(Money.of(USD, 100.0))
|
||||
.expirationDate(LocalDate.now().plusDays(10))
|
||||
.productDao(productDao)
|
||||
.build();
|
||||
}
|
||||
product =
|
||||
Product.builder()
|
||||
.name("product")
|
||||
.price(Money.of(USD, 100.0))
|
||||
.expirationDate(LocalDate.now().plusDays(10))
|
||||
.productDao(productDao)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldSaveProduct() throws SQLException {
|
||||
when(productDao.findByName("product")).thenReturn(Optional.empty());
|
||||
@Test
|
||||
void shouldSaveProduct() throws SQLException {
|
||||
when(productDao.findByName("product")).thenReturn(Optional.empty());
|
||||
|
||||
product.save();
|
||||
product.save();
|
||||
|
||||
verify(productDao, times(1)).save(product);
|
||||
verify(productDao, times(1)).save(product);
|
||||
|
||||
when(productDao.findByName("product")).thenReturn(Optional.of(product));
|
||||
when(productDao.findByName("product")).thenReturn(Optional.of(product));
|
||||
|
||||
product.save();
|
||||
product.save();
|
||||
|
||||
verify(productDao, times(1)).update(product);
|
||||
}
|
||||
verify(productDao, times(1)).update(product);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldGetSalePriceOfProduct() {
|
||||
assertEquals(Money.of(USD, 100), product.getSalePrice());
|
||||
@Test
|
||||
void shouldGetSalePriceOfProduct() {
|
||||
assertEquals(Money.of(USD, 100), product.getSalePrice());
|
||||
|
||||
product.setExpirationDate(LocalDate.now().plusDays(2));
|
||||
product.setExpirationDate(LocalDate.now().plusDays(2));
|
||||
|
||||
assertEquals(Money.of(USD, 80), product.getSalePrice());
|
||||
}
|
||||
assertEquals(Money.of(USD, 80), product.getSalePrice());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,13 +24,13 @@
|
||||
*/
|
||||
package com.iluwatar.domainmodel;
|
||||
|
||||
import org.h2.jdbcx.JdbcDataSource;
|
||||
import javax.sql.DataSource;
|
||||
import java.sql.SQLException;
|
||||
import javax.sql.DataSource;
|
||||
import org.h2.jdbcx.JdbcDataSource;
|
||||
|
||||
public class TestUtils {
|
||||
|
||||
public static void executeSQL( String sql, DataSource dataSource) throws SQLException {
|
||||
public static void executeSQL(String sql, DataSource dataSource) throws SQLException {
|
||||
try (var connection = dataSource.getConnection();
|
||||
var statement = connection.createStatement()) {
|
||||
statement.executeUpdate(sql);
|
||||
|
||||
Reference in New Issue
Block a user