Welcome to your second lesson, which continues to delve into Test Driven Development (TDD) practices using Java and JUnit. In this unit, we will extend the functionality of our calculateDiscount
function by implementing five new requirements.
Building on the previous unit, this course emphasizes practical experience by sequentially providing requirements through tests. Your mission is to implement code that satisfies each test, mirroring a real-world TDD scenario. Consider this guide your pair programmer, offering test-driven prompts to enhance your expertise incrementally.
As a reminder, the Red-Green-Refactor cycle is crucial in TDD, steering your development process:
- Red: Begin by writing a failing test to define what to do next.
- Green: Develop just enough code to pass the test, concentrating on meeting the functionality.
- Refactor: Enhance the code for clarity and efficiency without changing its behavior.
Below, you'll find additional requirements and tests designed to handle edge cases, such as negative discount percentages and capping maximum discounts.
These enhancements aim to ensure the calculateDiscount
function remains robust and reliable under various conditions.
- Description: The function should not accept negative discount percentages and must throw an error in such cases.
- Test Case:
Java1@Test 2public void testShouldThrowExceptionForDiscountsLessThanZeroPercent() { 3 // Arrange 4 double originalPrice = 100.0; 5 double discountPercentage = -10.0; 6 7 // Act & Assert 8 Exception exception = assertThrows(IllegalArgumentException.class, () -> { 9 CalculateDiscount.calculate(originalPrice, discountPercentage); 10 }); 11 assertEquals("Discount cannot be negative", exception.getMessage()); 12}
This test ensures that the function throws an exception when a negative discount percentage is provided.
- Description: The function should ensure that discounted prices don’t dip below the minimum limit due to very small original prices.
- Test Case:
Java1@Test 2public void testCalculateDiscountHandlesVerySmallPricesCorrectly() { 3 // Arrange 4 double originalPrice = 0.001; 5 double discountPercentage = 1.0; 6 double expectedDiscountedPrice = 0.01; // Should not go below 0.01 7 8 // Act 9 double result = CalculateDiscount.calculate(originalPrice, discountPercentage); 10 11 // Assert 12 assertEquals(expectedDiscountedPrice, result, 0.001); 13}
This test checks that the function prevents discounted prices from dropping below a specified minimum when dealing with very small prices.
- Description: Apply a minimum 1% discount if a lesser discount percentage is provided.
- Test Case:
Java1@Test 2public void testCalculateDiscountShouldApplyMinimumDiscountAmountWhenDiscountIsLessThanMinimum() { 3 // Arrange 4 double originalPrice = 100.0; 5 double discountPercentage = 0.1; // 0.1% discount 6 double expectedDiscountedPrice = 99.0; // Should apply minimum 1% discount 7 8 // Act 9 double result = CalculateDiscount.calculate(originalPrice, discountPercentage); 10 11 // Assert 12 assertEquals(expectedDiscountedPrice, result, 0.01); 13}
This test ensures that a minimum 1% discount is applied when the provided discount percentage is less than 1%.
- Description: Cap the discount amount at a max dollar value of $500, regardless of higher calculated discounts.
- Test Case:
Java1@Test 2public void testCalculateDiscountShouldCapMaximumDiscountAmountAt500() { 3 // Arrange 4 double originalPrice = 2500.0; 5 double discountPercentage = 30.0; // Would normally be $750 off 6 double expectedDiscountedPrice = 2000.0; // Should only apply $500 maximum discount 7 8 // Act 9 double result = CalculateDiscount.calculate(originalPrice, discountPercentage); 10 11 // Assert 12 assertEquals(expectedDiscountedPrice, result, 0.01); 13}
This test confirms that the discount calculation caps at a $500 maximum discount, even if the calculated discount exceeds this amount.
In this section, you implemented and tested advanced requirements for the CalculateDiscount
function. It included handling invalid, non-numeric inputs, securing very small prices to ensure payable amounts do not fall below defined levels, and applying specific discount constraints, including a minimum discount percentage and capping the maximum allowable discount.
As you proceed with practice exercises, remember the Red-Green-Refactor cycle to guide your method:
- Each test encourages you to sharpen the function's reliability by beginning with a “Red” phase, writing tests for new edge situations.
- Focus on passing each test in the “Green” phase by progressively implementing the necessary logic, like input validation and boundary enforcement.
- The “Refactor” phase lets you simplify and optimize your code post-testing success, ensuring it’s accurate and easily maintainable.
These exercises reinforce your TDD abilities by applying practical constraints and validations, simulating real-world scenarios where the robustness and reliability of code are pivotal.