Lesson 2
Continue Developing the calculateDiscount Function
Continue Developing the calculateDiscount Function

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.

Understanding the Red-Green-Refactor Cycle

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.
More Requirements for CalculateDiscount Function
6. Negative Discount Percentage
  • 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 }
7. Handling Very Small Prices
  • 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 }
8. Minimum Discount Percentage Application
  • 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 }
9. Capping Maximum Discount Amount
  • 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 }
Summary and Preparation for Practice Exercises

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.

Enjoy this lesson? Now it's time to practice with Cosmo!
Practice is how you turn knowledge into actual skills.