diff --git a/solutions/java/pom.xml b/solutions/java/pom.xml new file mode 100644 index 00000000..6b9c3bcd --- /dev/null +++ b/solutions/java/pom.xml @@ -0,0 +1,35 @@ + + 4.0.0 + coffeevendingmachine + coffeevendingmachine + 1.0-SNAPSHOT + jar + Coffee Vending Machine + + 1.8 + 1.8 + 5.10.2 + + + + org.junit.jupiter + junit-jupiter + ${junit.jupiter.version} + test + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 3.2.5 + + false + + + + + diff --git a/solutions/java/src/coffeevendingmachine/CoffeeVendingMachine.java b/solutions/java/src/coffeevendingmachine/CoffeeVendingMachine.java index 8b50a5a1..b4c25342 100644 --- a/solutions/java/src/coffeevendingmachine/CoffeeVendingMachine.java +++ b/solutions/java/src/coffeevendingmachine/CoffeeVendingMachine.java @@ -73,4 +73,8 @@ public void showIngredients() { System.out.println("Ingredient Levels:"); ingredientStore.getAllIngredients().forEach((k, v) -> System.out.println(k + ": " + v)); } + + public Map showIngredientsMap() { + return ingredientStore.getAllIngredients(); + } } diff --git a/solutions/java/test/coffeevendingmachine/CoffeeVendingMachineTest.java b/solutions/java/test/coffeevendingmachine/CoffeeVendingMachineTest.java new file mode 100644 index 00000000..34b3d03a --- /dev/null +++ b/solutions/java/test/coffeevendingmachine/CoffeeVendingMachineTest.java @@ -0,0 +1,116 @@ +package coffeevendingmachine; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.DisplayName; + +import static org.junit.jupiter.api.Assertions.*; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import java.util.Map; + +public class CoffeeVendingMachineTest { + + private CoffeeVendingMachine machine; + private final ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + private final PrintStream originalOut = System.out; + + @BeforeEach + void setUp() { + machine = CoffeeVendingMachine.getInstance(); + System.setOut(new PrintStream(outputStream)); + + // Reset and refill ingredients for each test + machine.refillIngredient("Water", 150); + machine.refillIngredient("Coffee", 100); + machine.refillIngredient("Milk", 100); + } + + @Test + @DisplayName("Test coffee selection") + void testSelectCoffee() { + CoffeeRecipe espresso = machine.selectCoffee("Espresso"); + assertEquals("Espresso", espresso.getName()); + assertEquals(2.5, espresso.getPrice()); + assertEquals(50, espresso.getRecipe().get("Water")); + assertEquals(20, espresso.getRecipe().get("Coffee")); + } + + @Test + @DisplayName("Test invalid coffee selection") + void testInvalidCoffeeSelection() { + Exception exception = assertThrows(RuntimeException.class, () -> { + machine.selectCoffee("MochaCoffee"); + }); + + String expectedMessage = "Invalid coffee recipe: MochaCoffee"; + String actualMessage = exception.getMessage(); + + assertTrue(actualMessage.contains(expectedMessage)); + } + + @Test + @DisplayName("Test successful coffee dispensing") + void testDispenseCoffee() { + CoffeeRecipe latte = machine.selectCoffee("Latte"); + machine.dispenseCoffee(latte, new Payment(4.0)); + + String output = outputStream.toString(); + assertTrue(output.contains("Dispensing: Latte")); + assertTrue(output.contains("Processing Payment")); + assertTrue(output.contains("Please collect your change: $1.0")); + } + + @Test + @DisplayName("Test insufficient payment") + void testInsufficientPayment() { + CoffeeRecipe cappuccino = machine.selectCoffee("Cappuccino"); + + Exception exception = assertThrows(RuntimeException.class, () -> { + machine.dispenseCoffee(cappuccino, new Payment(2.0)); + }); + + String expectedMessage = "Insufficient payment for Cappuccino"; + String actualMessage = exception.getMessage(); + + assertTrue(actualMessage.contains(expectedMessage)); + } + + + + @Test + @DisplayName("Test ingredient consumption") + void testIngredientConsumption() { + CoffeeRecipe latte = machine.selectCoffee("Latte"); + + // Check initial levels + Map beforeLevels = machine.showIngredientsMap(); + int initialWaterLevel = beforeLevels.get("Water"); + int initialCoffeeLevel = beforeLevels.get("Coffee"); + int initialMilkLevel = beforeLevels.get("Milk"); + + machine.dispenseCoffee(latte, new Payment(3.0)); + + // Check levels after dispensing + Map afterLevels = machine.showIngredientsMap(); + assertEquals(initialWaterLevel - 50, afterLevels.get("Water").intValue()); + assertEquals(initialCoffeeLevel - 20, afterLevels.get("Coffee").intValue()); + assertEquals(initialMilkLevel - 30, afterLevels.get("Milk").intValue()); + } + + @Test + @DisplayName("Test ingredient refill") + void testIngredientRefill() { + // First check initial level + Map beforeLevels = machine.showIngredientsMap(); + int initialWaterLevel = beforeLevels.get("Water"); + + // Add more water + machine.refillIngredient("Water", 50); + + // Check after refill + Map afterLevels = machine.showIngredientsMap(); + assertEquals(initialWaterLevel + 50, afterLevels.get("Water").intValue()); + } +}