Skip to content

Commit 426767d

Browse files
authored
Merge pull request #1 from WB3Tech-Java/add-money-classes
added money value object and tests
2 parents e873896 + f797342 commit 426767d

2 files changed

Lines changed: 238 additions & 0 deletions

File tree

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
package com.wb3tech.kernel.valueobject;
2+
3+
import java.math.BigDecimal;
4+
import java.math.RoundingMode;
5+
import java.util.Currency;
6+
import java.util.Objects;
7+
8+
public class Money {
9+
10+
private Currency currency;
11+
private BigDecimal amount = BigDecimal.valueOf(00.00);
12+
13+
Money(String currency) {
14+
this.setCurrency(currency);
15+
}
16+
17+
Money(double amount, String currency) {
18+
this.setAmount(amount);
19+
this.setCurrency(currency);
20+
}
21+
22+
Money(double amount, Currency currency) {
23+
this.setAmount(amount);
24+
this.setCurrency(currency);
25+
}
26+
27+
public static Money Of(String currency) {
28+
return new Money(currency);
29+
}
30+
31+
public static Money Of(double amount, String currency) {
32+
return new Money(amount, currency);
33+
}
34+
35+
public Money Plus(Money money) {
36+
if(this.isDifferentCurrency(money)) { throw new ArithmeticException("Cannot add monies of two different currencies."); }
37+
var totalAmount = this.amount.doubleValue() + money.getAmount();
38+
return new Money(totalAmount, this.currency);
39+
}
40+
41+
public Money Minus(Money money) {
42+
if(this.isDifferentCurrency(money)) { throw new ArithmeticException("Cannot subtract monies of two different currencies."); }
43+
var totalAmount = this.amount.doubleValue() - money.getAmount();
44+
return new Money(totalAmount, this.currency);
45+
}
46+
47+
public double getAmount() {
48+
return this.amount.doubleValue();
49+
}
50+
51+
public String getCurrency() {
52+
return this.currency.getCurrencyCode();
53+
}
54+
55+
public boolean equals(Money money) {
56+
if (this == money) return true;
57+
return Objects.equals(this.currency, money.currency) &&
58+
Objects.equals(this.amount, money.amount);
59+
}
60+
61+
private void setCurrency(String currency) {
62+
if(currency == null) { throw new IllegalArgumentException("You must provide a valid currency."); };
63+
this.currency = Currency.getInstance(currency);
64+
}
65+
66+
private void setCurrency(Currency currency) {
67+
this.currency = Currency.getInstance(currency.getCurrencyCode());
68+
}
69+
70+
private void setAmount(double amount) {
71+
this.amount = BigDecimal.valueOf(amount);
72+
this.amount= this.amount.setScale(2, RoundingMode.HALF_UP);
73+
}
74+
75+
private boolean isSameCurrency(Money money) {
76+
return this.currency.getCurrencyCode().equals(money.getCurrency());
77+
}
78+
79+
private boolean isDifferentCurrency(Money money) {
80+
return !this.isSameCurrency(money);
81+
}
82+
83+
}
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
package com.wb3tech.kernel.valueobject;
2+
3+
import org.junit.jupiter.api.Assertions;
4+
import org.junit.jupiter.api.DisplayName;
5+
import org.junit.jupiter.api.Tag;
6+
import org.junit.jupiter.api.Test;
7+
8+
import static org.junit.jupiter.api.Assertions.*;
9+
10+
@DisplayName("Kernel - Value Object - Money")
11+
public class MoneyTests {
12+
13+
14+
@Test @Tag("Small") @DisplayName("Should create a default money object with about equal to 00.00 and currency of 'USD'")
15+
public void DefaultMoney() {
16+
var money = Money.Of("USD");
17+
assertEquals(00.00, money.getAmount());
18+
assertEquals("USD", money.getCurrency());
19+
}
20+
21+
@Test @Tag("Small") @DisplayName("Should throw an IllegalArgumentException " +
22+
"with message 'You must provide a valid currency.'")
23+
public void ThrowIllegalArgumentExceptionForNullCurrency() {
24+
var exception = assertThrows(IllegalArgumentException.class, () -> Money.Of(null));
25+
Assertions.assertEquals("You must provide a valid currency.", exception.getMessage());
26+
27+
}
28+
29+
@Test @Tag("Small") @DisplayName("Should create Money object with 15.56 as amount and 'USD' as currency.")
30+
public void CreateMoney() {
31+
32+
var money = Money.Of(15.56, "USD");
33+
assertEquals(15.56, money.getAmount());
34+
assertEquals("USD", money.getCurrency());
35+
36+
}
37+
38+
@Test @Tag("Small") @DisplayName("Should create a money object with amount -200")
39+
public void ShouldCreateNegativeMoney() {
40+
41+
var negTwoHundred = Money.Of(-200, "USD");
42+
Assertions.assertEquals(-200, negTwoHundred.getAmount());
43+
44+
}
45+
46+
@Test @Tag("Small") @DisplayName("Should create Money object and round 15.566 up to 15.57 as amount and 'USD' as currency.")
47+
public void CreateMoneyRoundUp() {
48+
49+
var money = Money.Of(15.566, "USD");
50+
assertEquals(15.57, money.getAmount());
51+
assertEquals("USD", money.getCurrency());
52+
53+
}
54+
55+
@Test @Tag("Small") @DisplayName("Should create Money object and round 15.544 down to 15.54 as amount and 'USD' as currency.")
56+
public void CreateMoneyRoundDown() {
57+
58+
var money = Money.Of(15.544, "USD");
59+
assertEquals(15.54, money.getAmount());
60+
assertEquals("USD", money.getCurrency());
61+
62+
}
63+
64+
@Test @Tag("Small") @DisplayName("Should get a Money with amount of 13.33 when you add a money instance of 13.00 " +
65+
"and a second instance of 0.33")
66+
public void AddTwoMonies() {
67+
68+
var thirteen = Money.Of(13, "USD");
69+
var thirtyThreeCents = Money.Of(.33, "USD");
70+
var total = thirteen.Plus(thirtyThreeCents);
71+
72+
assertEquals(13.33, total.getAmount());
73+
assertEquals("USD", total.getCurrency());
74+
75+
}
76+
77+
@Test @Tag("Small") @DisplayName("Should get a Money with amount of 13.33 when you subtract a money instance of 13.66 " +
78+
"and a second instance of 0.33")
79+
public void SubtractTwoMonies() {
80+
81+
var thirteenSixtySix = Money.Of(13.66, "USD");
82+
var thirtyThreeCents = Money.Of(.33, "USD");
83+
var total = thirteenSixtySix.Minus(thirtyThreeCents);
84+
85+
assertEquals(13.33, total.getAmount());
86+
assertEquals("USD", total.getCurrency());
87+
88+
}
89+
90+
@Test @Tag("Small") @DisplayName("Should get a Money with amount of -5 when you subtract a money instance of 10 " +
91+
"and a second instance o 15")
92+
public void ShouldGetNegativeMoney() {
93+
94+
var ten = Money.Of(10, "USD");
95+
var fifteen = Money.Of(15, "USD");
96+
var total = ten.Minus(fifteen);
97+
98+
assertEquals(-5, total.getAmount());
99+
100+
}
101+
102+
@Test @Tag("Small") @DisplayName("Should throw an ArithmeticExceptionn" +
103+
"with message 'Cannot subtract monies of two different currencies'")
104+
public void SubtractShouldThrowArithmeticExceptionForNotSameCurrency() {
105+
106+
107+
var USDollar = Money.Of(13, "USD");
108+
var britishPounds = Money.Of(10, "GBP");
109+
110+
var exception = assertThrows(ArithmeticException.class, () -> USDollar.Minus(britishPounds));
111+
Assertions.assertEquals("Cannot subtract monies of two different currencies.", exception.getMessage());
112+
113+
114+
}
115+
116+
@Test @Tag("Small") @DisplayName("Should throw an ArithmeticException " +
117+
"with message 'Cannot add monies of two different currencies'")
118+
public void AddShouldThrowArithmeticExceptionForNotSameCurrency() {
119+
120+
var USDollar = Money.Of(13, "USD");
121+
var britishPounds = Money.Of(10, "GBP");
122+
123+
var exception = assertThrows(ArithmeticException.class, () -> USDollar.Plus(britishPounds));
124+
Assertions.assertEquals("Cannot add monies of two different currencies.", exception.getMessage());
125+
126+
}
127+
128+
@Test @Tag("Small") @DisplayName("A money instance of $1 should equal the second instance of $1")
129+
public void ShouldEqual() {
130+
131+
var firstDollarInstance = Money.Of(1, "USD");
132+
var secondDollarInstance = Money.Of(1, "USD");
133+
134+
assertTrue(firstDollarInstance.equals(secondDollarInstance));
135+
}
136+
137+
@Test @Tag("Small") @DisplayName("A money instance of $1 should not an instnace of 1 GBP")
138+
public void TwoDifferentCurrenciesShouldNotEqual() {
139+
140+
var oneDollar = Money.Of(1, "USD");
141+
var oneGBP = Money.Of(1, "GBP");
142+
143+
assertFalse(oneDollar.equals(oneGBP));
144+
}
145+
146+
@Test @Tag("Small") @DisplayName("A money instance of $1 should equal the second instance of $1")
147+
public void TwoDifferentAmountsShouldNotEqual() {
148+
149+
var oneDollar = Money.Of(1, "USD");
150+
var twoDollar = Money.Of(2, "USD");
151+
152+
assertFalse(oneDollar.equals(twoDollar));
153+
}
154+
155+
}

0 commit comments

Comments
 (0)