Add BAEL-2272 persisting DDD aggregates examples (#5630)
* Add BAEL-2272 persisting DDD aggregates examples * Update pom.xml
This commit is contained in:
parent
91ec114e9a
commit
e1056e04de
|
@ -0,0 +1,91 @@
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
|
<version>2.0.6.RELEASE</version>
|
||||||
|
<relativePath /> <!-- lookup parent from repository -->
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<groupId>com.baeldung.ddd</groupId>
|
||||||
|
<artifactId>ddd</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
<name>ddd</name>
|
||||||
|
<description>DDD series examples</description>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<joda-money.version>1.0.1</joda-money.version>
|
||||||
|
<maven-surefire-plugin.version>2.22.0</maven-surefire-plugin.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-data-mongodb</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.junit.jupiter</groupId>
|
||||||
|
<artifactId>junit-jupiter-api</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.junit.jupiter</groupId>
|
||||||
|
<artifactId>junit-jupiter-engine</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<!-- JUnit platform launcher -->
|
||||||
|
<!-- To be able to run tests from IDE directly -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.junit.platform</groupId>
|
||||||
|
<artifactId>junit-platform-launcher</artifactId>
|
||||||
|
<version>${junit-platform.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.joda</groupId>
|
||||||
|
<artifactId>joda-money</artifactId>
|
||||||
|
<version>${joda-money.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.h2database</groupId>
|
||||||
|
<artifactId>h2</artifactId>
|
||||||
|
<scope>runtime</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>mysql</groupId>
|
||||||
|
<artifactId>mysql-connector-java</artifactId>
|
||||||
|
<scope>runtime</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.postgresql</groupId>
|
||||||
|
<artifactId>postgresql</artifactId>
|
||||||
|
<scope>runtime</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-devtools</artifactId>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>de.flapdoodle.embed</groupId>
|
||||||
|
<artifactId>de.flapdoodle.embed.mongo</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
|
@ -0,0 +1,12 @@
|
||||||
|
package com.baeldung.ddd;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
public class PersistingDddAggregatesApplication {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(PersistingDddAggregatesApplication.class, args);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
package com.baeldung.ddd.order;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.joda.money.Money;
|
||||||
|
|
||||||
|
public class Order {
|
||||||
|
private final List<OrderLine> orderLines;
|
||||||
|
private Money totalCost;
|
||||||
|
|
||||||
|
public Order(List<OrderLine> orderLines) {
|
||||||
|
checkNotNull(orderLines);
|
||||||
|
if (orderLines.isEmpty()) {
|
||||||
|
throw new IllegalArgumentException("Order must have at least one order line item");
|
||||||
|
}
|
||||||
|
this.orderLines = new ArrayList<>(orderLines);
|
||||||
|
totalCost = calculateTotalCost();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addLineItem(OrderLine orderLine) {
|
||||||
|
checkNotNull(orderLine);
|
||||||
|
orderLines.add(orderLine);
|
||||||
|
totalCost = totalCost.plus(orderLine.cost());
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<OrderLine> getOrderLines() {
|
||||||
|
return new ArrayList<>(orderLines);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeLineItem(int line) {
|
||||||
|
OrderLine removedLine = orderLines.remove(line);
|
||||||
|
totalCost = totalCost.minus(removedLine.cost());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Money totalCost() {
|
||||||
|
return totalCost;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Money calculateTotalCost() {
|
||||||
|
return orderLines.stream()
|
||||||
|
.map(OrderLine::cost)
|
||||||
|
.reduce(Money::plus)
|
||||||
|
.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void checkNotNull(Object par) {
|
||||||
|
if (par == null) {
|
||||||
|
throw new NullPointerException("Parameter cannot be null");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,67 @@
|
||||||
|
package com.baeldung.ddd.order;
|
||||||
|
|
||||||
|
import org.joda.money.Money;
|
||||||
|
|
||||||
|
public class OrderLine {
|
||||||
|
private final Product product;
|
||||||
|
private final int quantity;
|
||||||
|
|
||||||
|
public OrderLine(Product product, int quantity) {
|
||||||
|
super();
|
||||||
|
this.product = product;
|
||||||
|
this.quantity = quantity;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (obj == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (getClass() != obj.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
OrderLine other = (OrderLine) obj;
|
||||||
|
if (product == null) {
|
||||||
|
if (other.product != null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (!product.equals(other.product)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (quantity != other.quantity) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = 1;
|
||||||
|
result = prime * result + ((product == null) ? 0 : product.hashCode());
|
||||||
|
result = prime * result + quantity;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "OrderLine [product=" + product + ", quantity=" + quantity + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
Money cost() {
|
||||||
|
return product.getPrice()
|
||||||
|
.multipliedBy(quantity);
|
||||||
|
}
|
||||||
|
|
||||||
|
Product getProduct() {
|
||||||
|
return product;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getQuantity() {
|
||||||
|
return quantity;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
package com.baeldung.ddd.order;
|
||||||
|
|
||||||
|
import org.joda.money.Money;
|
||||||
|
|
||||||
|
public class Product {
|
||||||
|
private final Money price;
|
||||||
|
|
||||||
|
public Product(Money price) {
|
||||||
|
super();
|
||||||
|
this.price = price;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (obj == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (getClass() != obj.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Product other = (Product) obj;
|
||||||
|
if (price == null) {
|
||||||
|
if (other.price != null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (!price.equals(other.price)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = 1;
|
||||||
|
result = prime * result + ((price == null) ? 0 : price.hashCode());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Product [price=" + price + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
Money getPrice() {
|
||||||
|
return price;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,111 @@
|
||||||
|
package com.baeldung.ddd.order.jpa;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.persistence.ElementCollection;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.FetchType;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "order_table")
|
||||||
|
class JpaOrder {
|
||||||
|
private String currencyUnit;
|
||||||
|
@Id
|
||||||
|
@GeneratedValue
|
||||||
|
private Long id;
|
||||||
|
@ElementCollection(fetch = FetchType.EAGER)
|
||||||
|
private final List<JpaOrderLine> orderLines;
|
||||||
|
private BigDecimal totalCost;
|
||||||
|
|
||||||
|
JpaOrder() {
|
||||||
|
totalCost = null;
|
||||||
|
orderLines = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
JpaOrder(List<JpaOrderLine> orderLines) {
|
||||||
|
checkNotNull(orderLines);
|
||||||
|
if (orderLines.isEmpty()) {
|
||||||
|
throw new IllegalArgumentException("Order must have at least one order line item");
|
||||||
|
}
|
||||||
|
this.orderLines = new ArrayList<>(orderLines);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (obj == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (getClass() != obj.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
JpaOrder other = (JpaOrder) obj;
|
||||||
|
if (id == null) {
|
||||||
|
if (other.id != null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (!id.equals(other.id)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = 1;
|
||||||
|
result = prime * result + ((id == null) ? 0 : id.hashCode());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "JpaOrder [currencyUnit=" + currencyUnit + ", id=" + id + ", orderLines=" + orderLines + ", totalCost=" + totalCost + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
void addLineItem(JpaOrderLine orderLine) {
|
||||||
|
checkNotNull(orderLine);
|
||||||
|
orderLines.add(orderLine);
|
||||||
|
}
|
||||||
|
|
||||||
|
String getCurrencyUnit() {
|
||||||
|
return currencyUnit;
|
||||||
|
}
|
||||||
|
|
||||||
|
Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<JpaOrderLine> getOrderLines() {
|
||||||
|
return new ArrayList<>(orderLines);
|
||||||
|
}
|
||||||
|
|
||||||
|
BigDecimal getTotalCost() {
|
||||||
|
return totalCost;
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeLineItem(int line) {
|
||||||
|
JpaOrderLine removedLine = orderLines.remove(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setCurrencyUnit(String currencyUnit) {
|
||||||
|
this.currencyUnit = currencyUnit;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setTotalCost(BigDecimal totalCost) {
|
||||||
|
this.totalCost = totalCost;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void checkNotNull(Object par) {
|
||||||
|
if (par == null) {
|
||||||
|
throw new NullPointerException("Parameter cannot be null");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,70 @@
|
||||||
|
package com.baeldung.ddd.order.jpa;
|
||||||
|
|
||||||
|
import javax.persistence.Embeddable;
|
||||||
|
import javax.persistence.Embedded;
|
||||||
|
|
||||||
|
@Embeddable
|
||||||
|
class JpaOrderLine {
|
||||||
|
@Embedded
|
||||||
|
private final JpaProduct product;
|
||||||
|
private final int quantity;
|
||||||
|
|
||||||
|
JpaOrderLine() {
|
||||||
|
quantity = 0;
|
||||||
|
product = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
JpaOrderLine(JpaProduct product, int quantity) {
|
||||||
|
super();
|
||||||
|
this.product = product;
|
||||||
|
this.quantity = quantity;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (obj == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (getClass() != obj.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
JpaOrderLine other = (JpaOrderLine) obj;
|
||||||
|
if (product == null) {
|
||||||
|
if (other.product != null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (!product.equals(other.product)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (quantity != other.quantity) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = 1;
|
||||||
|
result = prime * result + ((product == null) ? 0 : product.hashCode());
|
||||||
|
result = prime * result + quantity;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "JpaOrderLine [product=" + product + ", quantity=" + quantity + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
JpaProduct getProduct() {
|
||||||
|
return product;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getQuantity() {
|
||||||
|
return quantity;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
package com.baeldung.ddd.order.jpa;
|
||||||
|
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
|
||||||
|
public interface JpaOrderRepository extends JpaRepository<JpaOrder, Long> {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,79 @@
|
||||||
|
package com.baeldung.ddd.order.jpa;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
import javax.persistence.Embeddable;
|
||||||
|
|
||||||
|
@Embeddable
|
||||||
|
class JpaProduct {
|
||||||
|
private String currencyUnit;
|
||||||
|
private BigDecimal price;
|
||||||
|
|
||||||
|
public JpaProduct() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public JpaProduct(BigDecimal price, String currencyUnit) {
|
||||||
|
super();
|
||||||
|
this.price = price;
|
||||||
|
currencyUnit = currencyUnit;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (obj == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (getClass() != obj.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
JpaProduct other = (JpaProduct) obj;
|
||||||
|
if (currencyUnit == null) {
|
||||||
|
if (other.currencyUnit != null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (!currencyUnit.equals(other.currencyUnit)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (price == null) {
|
||||||
|
if (other.price != null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (!price.equals(other.price)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCurrencyUnit() {
|
||||||
|
return currencyUnit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BigDecimal getPrice() {
|
||||||
|
return price;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = 1;
|
||||||
|
result = prime * result + ((currencyUnit == null) ? 0 : currencyUnit.hashCode());
|
||||||
|
result = prime * result + ((price == null) ? 0 : price.hashCode());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCurrencyUnit(String currencyUnit) {
|
||||||
|
this.currencyUnit = currencyUnit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPrice(BigDecimal price) {
|
||||||
|
this.price = price;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "JpaProduct [currencyUnit=" + currencyUnit + ", price=" + price + "]";
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
package com.baeldung.ddd.order.mongo;
|
||||||
|
|
||||||
|
import org.springframework.data.mongodb.repository.MongoRepository;
|
||||||
|
|
||||||
|
import com.baeldung.ddd.order.Order;
|
||||||
|
|
||||||
|
public interface OrderMongoRepository extends MongoRepository<Order, String> {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,70 @@
|
||||||
|
package com.baeldung.ddd.order;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.assertj.core.api.Assertions.catchThrowable;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import org.joda.money.CurrencyUnit;
|
||||||
|
import org.joda.money.Money;
|
||||||
|
import org.junit.jupiter.api.DisplayName;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
class OrderTest {
|
||||||
|
@DisplayName("given order with two items, when calculate total cost, then sum is returned")
|
||||||
|
@Test
|
||||||
|
void test0() throws Exception {
|
||||||
|
// given
|
||||||
|
OrderLine ol0 = new OrderLine(new Product(Money.of(CurrencyUnit.USD, 10.00)), 2);
|
||||||
|
OrderLine ol1 = new OrderLine(new Product(Money.of(CurrencyUnit.USD, 5.00)), 10);
|
||||||
|
Order order = new Order(Arrays.asList(ol0, ol1));
|
||||||
|
|
||||||
|
// when
|
||||||
|
Money totalCost = order.totalCost();
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(totalCost).isEqualTo(Money.of(CurrencyUnit.USD, 70.00));
|
||||||
|
}
|
||||||
|
|
||||||
|
@DisplayName("when create order without line items, then exception is thrown")
|
||||||
|
@Test
|
||||||
|
void test1() throws Exception {
|
||||||
|
// when
|
||||||
|
Throwable throwable = catchThrowable(() -> new Order(new ArrayList<>()));
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(throwable).isInstanceOf(IllegalArgumentException.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@DisplayName("given order with two line items, when add another line item, then total cost is updated")
|
||||||
|
@Test
|
||||||
|
void test2() throws Exception {
|
||||||
|
// given
|
||||||
|
OrderLine ol0 = new OrderLine(new Product(Money.of(CurrencyUnit.USD, 10.00)), 1);
|
||||||
|
OrderLine ol1 = new OrderLine(new Product(Money.of(CurrencyUnit.USD, 5.00)), 1);
|
||||||
|
Order order = new Order(Arrays.asList(ol0, ol1));
|
||||||
|
|
||||||
|
// when
|
||||||
|
order.addLineItem(new OrderLine(new Product(Money.of(CurrencyUnit.USD, 20.00)), 2));
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(order.totalCost()).isEqualTo(Money.of(CurrencyUnit.USD, 55));
|
||||||
|
}
|
||||||
|
|
||||||
|
@DisplayName("given order with three line items, when remove item, then total cost is updated")
|
||||||
|
@Test
|
||||||
|
void test3() throws Exception {
|
||||||
|
// given
|
||||||
|
OrderLine ol0 = new OrderLine(new Product(Money.of(CurrencyUnit.USD, 10.00)), 1);
|
||||||
|
OrderLine ol1 = new OrderLine(new Product(Money.of(CurrencyUnit.USD, 20.00)), 1);
|
||||||
|
OrderLine ol2 = new OrderLine(new Product(Money.of(CurrencyUnit.USD, 30.00)), 1);
|
||||||
|
Order order = new Order(Arrays.asList(ol0, ol1, ol2));
|
||||||
|
|
||||||
|
// when
|
||||||
|
order.removeLineItem(1);
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(order.totalCost()).isEqualTo(Money.of(CurrencyUnit.USD, 40.00));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
package com.baeldung.ddd.order.jpa;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.DisplayName;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
|
||||||
|
|
||||||
|
@SpringJUnitConfig
|
||||||
|
@SpringBootTest
|
||||||
|
public class PersistOrderIntegrationTest {
|
||||||
|
@Autowired
|
||||||
|
private JpaOrderRepository repository;
|
||||||
|
|
||||||
|
@DisplayName("given order with two line items, when persist, then order is saved")
|
||||||
|
@Test
|
||||||
|
public void test() throws Exception {
|
||||||
|
// given
|
||||||
|
JpaOrder order = prepareTestOrderWithTwoLineItems();
|
||||||
|
|
||||||
|
// when
|
||||||
|
JpaOrder savedOrder = repository.save(order);
|
||||||
|
|
||||||
|
// then
|
||||||
|
JpaOrder foundOrder = repository.findById(savedOrder.getId())
|
||||||
|
.get();
|
||||||
|
assertThat(foundOrder.getOrderLines()).hasSize(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
private JpaOrder prepareTestOrderWithTwoLineItems() {
|
||||||
|
JpaOrderLine ol0 = new JpaOrderLine(new JpaProduct(BigDecimal.valueOf(10.00), "USD"), 2);
|
||||||
|
JpaOrderLine ol1 = new JpaOrderLine(new JpaProduct(BigDecimal.valueOf(5.00), "USD"), 10);
|
||||||
|
return new JpaOrder(Arrays.asList(ol0, ol1));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
package com.baeldung.ddd.order.jpa;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.DisplayName;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
public class ViolateOrderBusinessRulesTest {
|
||||||
|
@DisplayName("given two non-zero order line items, when create an order with them, it's possible to set total cost to zero")
|
||||||
|
@Test
|
||||||
|
void test() throws Exception {
|
||||||
|
// given
|
||||||
|
// available products
|
||||||
|
JpaProduct lungChingTea = new JpaProduct(BigDecimal.valueOf(10.00), "USD");
|
||||||
|
JpaProduct gyokuroMiyazakiTea = new JpaProduct(BigDecimal.valueOf(20.00), "USD");
|
||||||
|
// Lung Ching tea order line
|
||||||
|
JpaOrderLine orderLine0 = new JpaOrderLine(lungChingTea, 2);
|
||||||
|
// Gyokuro Miyazaki tea order line
|
||||||
|
JpaOrderLine orderLine1 = new JpaOrderLine(gyokuroMiyazakiTea, 3);
|
||||||
|
|
||||||
|
// when
|
||||||
|
// create the order
|
||||||
|
JpaOrder order = new JpaOrder();
|
||||||
|
order.addLineItem(orderLine0);
|
||||||
|
order.addLineItem(orderLine1);
|
||||||
|
order.setTotalCost(BigDecimal.ZERO);
|
||||||
|
order.setCurrencyUnit("USD");
|
||||||
|
|
||||||
|
// then
|
||||||
|
// this doesn't look good...
|
||||||
|
assertThat(order.getTotalCost()).isEqualTo(BigDecimal.ZERO);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
package com.baeldung.ddd.order.mongo;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.joda.money.CurrencyUnit;
|
||||||
|
import org.joda.money.Money;
|
||||||
|
import org.junit.jupiter.api.DisplayName;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
|
||||||
|
|
||||||
|
import com.baeldung.ddd.order.Order;
|
||||||
|
import com.baeldung.ddd.order.OrderLine;
|
||||||
|
import com.baeldung.ddd.order.Product;
|
||||||
|
|
||||||
|
@SpringJUnitConfig
|
||||||
|
@SpringBootTest
|
||||||
|
public class OrderMongoIntegrationTest {
|
||||||
|
@Autowired
|
||||||
|
private OrderMongoRepository repo;
|
||||||
|
|
||||||
|
@DisplayName("given order with two line items, when persist using mongo repository, then order is saved")
|
||||||
|
@Test
|
||||||
|
void test() throws Exception {
|
||||||
|
// given
|
||||||
|
Order order = prepareTestOrderWithTwoLineItems();
|
||||||
|
|
||||||
|
// when
|
||||||
|
repo.save(order);
|
||||||
|
|
||||||
|
// then
|
||||||
|
List<Order> foundOrders = repo.findAll();
|
||||||
|
assertThat(foundOrders).hasSize(1);
|
||||||
|
List<OrderLine> foundOrderLines = foundOrders.iterator()
|
||||||
|
.next()
|
||||||
|
.getOrderLines();
|
||||||
|
assertThat(foundOrderLines).hasSize(2);
|
||||||
|
assertThat(foundOrderLines).containsOnlyElementsOf(order.getOrderLines());
|
||||||
|
}
|
||||||
|
|
||||||
|
private Order prepareTestOrderWithTwoLineItems() {
|
||||||
|
OrderLine ol0 = new OrderLine(new Product(Money.of(CurrencyUnit.USD, 10.00)), 2);
|
||||||
|
OrderLine ol1 = new OrderLine(new Product(Money.of(CurrencyUnit.USD, 5.00)), 10);
|
||||||
|
return new Order(Arrays.asList(ol0, ol1));
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue