Welcome to your second lesson, which continues to delve into Test Driven Development (TDD) practices using a new C# and xUnit. 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.
- Description: The function should not accept negative discount percentages and must throw an error in such cases.
- Test Case:
C#
1 [Fact] 2 public void Should_Throw_Exception_For_Discounts_Less_Than_ZeroPercent() 3 { 4 // Arrange 5 decimal originalPrice = 100; 6 decimal discountPercentage = -10; 7 8 // Act & Assert 9 var exception = Assert.Throws<ArgumentException>(() => CalculateDiscount(originalPrice, discountPercentage)); 10 Assert.Equal("Discount cannot be negative", exception.Message); 11 }
- Description: The function should ensure that discounted prices don’t dip below the minimum limit due to very small original prices.
- Test Case:
C#
1 [Fact] 2 public void CalculateDiscount_HandlesVerySmallPricesCorrectly() 3 { 4 // Arrange 5 var math = new Math(); 6 var originalPrice = 0.001; 7 var discountPercentage = 1; 8 var expectedDiscountedPrice = 0.01; // Should not go below 0.01 9 10 // Act 11 var result = math.CalculateDiscount(originalPrice, discountPercentage); 12 13 // Assert 14 Assert.Equal(expectedDiscountedPrice, result); 15 }
- Description: Apply a minimum 1% discount if a lesser discount percentage is provided.
- Test Case:
C#
1 [Fact] 2 public void CalculateDiscount_ShouldApplyMinimumDiscountAmountWhenDiscountIsLessThanMinimum() 3 { 4 // Arrange 5 var math = new Math(); 6 double originalPrice = 100; 7 double discountPercentage = 0.1; // 0.1% discount 8 double expectedDiscountedPrice = 99; // Should apply minimum 1% discount 9 10 // Act 11 var result = math.CalculateDiscount(originalPrice, discountPercentage); 12 13 // Assert 14 Assert.Equal(expectedDiscountedPrice, result, 2); 15 }
- Description: Cap the discount amount at a max dollar value of $500, regardless of higher calculated discounts.
- Test Case:
C#
1 [Fact] 2 public void CalculateDiscount_ShouldCapMaximumDiscountAmountAt500() 3 { 4 // Arrange 5 var math = new Math(); 6 double originalPrice = 2500; 7 double discountPercentage = 30; // Would normally be $750 off 8 double expectedDiscountedPrice = 2000; // Should only apply $500 maximum discount 9 10 // Act 11 var result = math.CalculateDiscount(originalPrice, discountPercentage); 12 13 // Assert 14 Assert.Equal(expectedDiscountedPrice, result); 15 }
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 max 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.