官术网_书友最值得收藏!

3.4 檢測異常

當編寫測試時,必須確保包含對于無效值的測試。例如,如果方法中輸入一個負數作為利率將會發生什么?這種情況是不允許發生的,所以應該拋出一個異常。通常情況下,如果在業務邏輯中拋出一個異常,我們會把這個異常當作測試失敗。但是在測試環境中,這個異常是要作為測試成功來處理的。為了實現這個,我們將使用ExpectedException屬性。

如代碼清單3.8所示,我們更新當前的業務邏輯。

代碼清單3.8 拋出一個異常的方法


using System;
namespace CodeSamples.Ch03_UnitTesting.Listing8
{
  public class FinancialFunctions
  {
    /// <summary>
    /// P = (Pv*R) / [1 - (1 + R)^(-n)]
    /// where
    ///     Pv  = Present Value (beginning
    ///           value or amount of loan)
    ///     APR = Annual Percentage Rate
    ///           (one year time period)
    ///     R   = Periodic Interest Rate =
    ///           APR/ # of interest periods per year
    ///     P   = Monthly Payment
    ///     n   = # of interest periods for overall
    ///           time period (i.e., interest
    ///           periods per year * number of years)
    /// </summary>
    /// <param name="pLoanAmount">Original amount of the loan</param>
    /// <param name="pYearlyInterestRate">Yearly interest rate</param>
    /// <param name="pNumMonthlyPayments">Num of mthly payments</param>
    /// <returns></returns>
    public double CalcLoanPayment(double pLoanAmount,
      double pYearlyInterestRate, int pNumMonthlyPayments)
    {
      //start code change *******************************
      if (pYearlyInterestRate < 0)
        throw new ArgumentException(
          "pYearlyInterestRate cannot be negative");
      //end code change *******************************
      var mthlyInterestRate = pYearlyInterestRate / 1200;
      var numerator = pLoanAmount * mthlyInterestRate;
      var denominator = (1 - Math.Pow(1 + mthlyInterestRate,
            -pNumMonthlyPayments));
      var mthlyPayment = Math.Round(numerator / denominator, 2);
      return mthlyPayment;
    }
  }
}

有了這個業務邏輯,我們就可以編寫一個如代碼清單3.9所示的測試以確保拋出異常。代碼清單3.9展示了將新測試加到已有測試頂部。

代碼清單3.9 測試拋出一個異常的方法


using System;
using CodeSamples.Ch03_UnitTesting.Listing8;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace CodeSamples.Ch03_UnitTesting.Listing9
{
  [TestClass]
  public class FinancialFunctionsUnitTest
  {
    [TestMethod]
    [ExpectedException(typeof(ArgumentException))]
    public void CalcLoanPayment_Loan1000IntNeg10Pmt12_Throws()
    {
      //Arrange
      var ex = new FinancialFunctions();
      //Act
      ex.CalcLoanPayment(1000, -10, 12);
    }
    [TestMethod]
    public void CalcLoanPayment_Loan1000Int10Pmt360_ReturnsPmt()
    {
      //Arrange
      var ex = new FinancialFunctions();
      //Act
      var pmt = ex.CalcLoanPayment(1000, 10, 360);
      //Assert
      Assert.AreEqual(8.78, pmt);
    }
    [TestMethod]
    public void CalcLoanPayment_Loan1000Int5Pmt360_ReturnsPmt()
    {
      //Arrange
      var ex = new FinancialFunctions();
      //Act
      var pmt = ex.CalcLoanPayment(1000, 15, 360);
      //Assert
      Assert.AreEqual(12.64, pmt);
    }
    [TestMethod]
    public void CalcLoanPayment_Loan1000Int10Pmt12_ReturnsPmt()
    {
      //Arrange
      var ex = new FinancialFunctions();
      //Act
      var pmt = ex.CalcLoanPayment(1000, 10, 12);
      //Assert
      Assert.AreEqual(87.92, pmt);
    }
  }
}

在第一個測試里,注意TestMethod屬性后的ExpectedException屬性。另一個要注意的是Assert聲明沒有出現。其實并不需要Assert,因為當拋出異常時測試就停止執行了。如果不拋出異常,則由于ExpectedException屬性的存在,測試就會失敗。測試的最終結果如圖3.8所示。

圖3.8 4個測試都已通過

主站蜘蛛池模板: 库伦旗| 廊坊市| 苗栗县| 从江县| 新郑市| 渭南市| 沁水县| 巫山县| 青川县| 曲周县| 新竹县| 商南县| 五华县| 湟源县| 巧家县| 铜鼓县| 定日县| 阿图什市| 宜兰市| 达州市| 康保县| 新和县| 旬邑县| 永州市| 桐城市| 通化县| 松江区| 河西区| 庄浪县| 五指山市| 济源市| 南宁市| 修武县| 二连浩特市| 祁东县| 南康市| 贵南县| 胶州市| 藁城市| 佛学| 建始县|