Code refactoring and unit testing — moving methods to appropriate [dependent] classes (6)

Time:2022-5-24
 

6、 Reconstruction3: move the method to the appropriate [dependent] class

After previous refactoring (see article)Code refactoring and unit testing — refactoring of “extraction method” (3)AndCode refactoring and unit testing — refactoring method parameters (5)), we extracted two methods from the statement () method. Looking at the two reconstructed methods, it is not difficult to see that the two encapsulated new methods only need one parameter, which is the object of the rental class. That is, both methods depend on the rental class, but not on the current class where the method is located. The reason for this is that these two methods are misplaced, because they are placed in the customer class, but do not depend on the customer class and depend on the rental class, which is enough to explain that these two methods should be placed in the rental class.

1. After simple analysis, we can decide to put the newly extracted method into the rental class and remove the parameters of the method. Because the method is in the rental class, you can use this directly in the method. Move the method of calculating the amount and the method of calculating the integral to the rental class.

2. Open rental in the visual studio 2019 code editor CS file, the getamount and getfrequentrenterpoints methods from customer CS file to rental CS file. The specific code is as follows:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;


namespace LeasePowerBank
{

    /// 
    ///Leasing
    /// 
    public class Rental
    {

      public  PowerBank Power ; // Name of power bank
        public int RentedTime;// Lease time

        public Rental(PowerBank powerbk,int rentedTime)
        {

            Power = powerbk;
            RentedTime = rentedTime;
        }


        public int GetFrequentRenterPoints()
        {

            int frequentRenterPoints = 0;
 
            decimal amount = GetAmount();
            //Calculate integral
            if (this.Power.PriceCode == PowerBank.HighTraffic && this.RentedTime > 4)

            {
                frequentRenterPoints += (int)Math.Ceiling(amount * 1.5M);

            }
            else
                frequentRenterPoints += (int)Math.Ceiling(amount);

            return frequentRenterPoints;
        }

        /// 
        ///Calculate the total amount according to the order of power bank
        /// 
        /// 
        /// 
       public decimal GetAmount()
        {
            decimal amount = 0M;


            switch (this.Power.PriceCode)
            {
                case 0:
                    amount = this.RentedTime;
                    if (this.RentedTime > 12)
                    {
                        amount = 12;
                    }
                    break;
                case 1:
                    amount = this.RentedTime * 3;
                    if (this.RentedTime > 24)
                    {
                        amount = 24;
                    }
                    break;
                case 2:
 
                    amount = this.RentedTime * 5;
                    if (this.RentedTime > 50)
                    {
                        amount = 50;
                    }
                    break;
                default:
                    break;
            }
            return amount;
        }

   }
}

 

3. The code in the statement () method in our customer also needs to be modified. When calculating the amount and integral, directly call the method in rental. The code is as follows:

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace LeasePowerBank
{

    /// 
      ///Customer class
    /// 
   public  class Customer
    {

        string Name;// User name
    public    List listRentals=new List();// User leased power bank

        public Customer(string name)
        {

            Name = name;
        }
        public void AddRental(Rental rental)
        {
            listRentals.Add(rental);
        }


        public string Statement()
        {

            decimal totalAmount = 0M; // Total amount
            int frequentRenterPoints = 0; // User points
            String result = $"{name}" lease Bill: \ n ";

          
            foreach (var item in listRentals)
            {
                decimal amount = item. GetAmount();// Total price calculation
                totalAmount += amount;

                frequentRenterPoints = item.GetFrequentRenterPoints();
            }

 
            Result + = $"total amount: {totalamount} \ n";
            Result + = $"you have obtained: {frequentrenterpoints} points this time";

            return result;

        }
    }
}

 

4. Open unittest1 in the test project leasepowerbanktest in Visual Studio 2019 CS test class file, we also need to modify the test cases in unit testing. Modify the method in the customer class to call the method in the rental class. The code is as follows:

[TestMethod]
        public void ValidGetAmountTest()
        {
            double expected = 5;

            //Create user
            Var customer = new customer ("Zhang San");

            //Create a power bank
            Powerbank regularpowerbank = new powerbank ("low - power bank", powerbank. Lowtraffic);
 

            //Create lease data
            var rental1 = new Rental(regularPowerBank, 5);

            // Act
            double actual = (double)rental1.GetAmount();

            // Assert      
            Assert. Areequal (expected, actual, 0.001, $"total amount calculation error, actual calculation amount {actual}, expected amount: {expected}");

        }

        [TestMethod]
        public void ValidGetFrequentRenterPointsTest()
        {
            int expected = 5;
            //Create user
            Var customer = new customer ("Zhang San");
            //Create a power bank
            Powerbank regularpowerbank = new powerbank ("low - power bank", powerbank. Lowtraffic);

 
            //Create lease data
            var rental1 = new Rental(regularPowerBank, 5);
            // Act
            int actual = rental1.GetFrequentRenterPoints();

            // Assert
            Assert. Areequal (expected, actual, 0.001, "integral calculation error");
        }

 

  5. Find the menu item “test — > run all tests” on the menu bar of visual studio 2019. Or select “run all tests in view” button in “test Explorer” to run test cases. Monitor whether the reconstruction results are correct. As shown below.