四、重构1的单元测试
程序开发过程中,写代码是为了实现需求。当我们的代码通过了编译,只是说明它的语法正确,功能能否实现则不能保证。 因此,当我们的某些功能代码完成后,为了检验其是否满足程序的需求。可以通过编写测试代码,模拟程序运行的过程,检验功能代码是否符合预期。
单元测试就是开发者编写一小段代码,检验目标代码的功能是否符合预期。通常情况下,单元测试主要面向一些功能单一的模块进行。
举个例子:一部手机有许多零部件组成,在正式组装一部手机前,手机内部的各个零部件,CPU、内存、存储、电池、摄像头、按键等,都要进行测试,这就是单元测试。
单元测试实际上就是一些“断言”(assert)代码。断言就是判断一个方法或对象的一个方法所产生的结果是否符合你期望的那个结果。单元测试中,一般使用assert来判断结果,如果表达式为真则通过,如果表达式为假会发生异常。
在 代码重构与单元测试——“提取方法”重构(三) 的文章中我们已经进行了“提取方法”重构,今天我们要写一个测试用例,然后执行一下单元测试,来看看我们之前的“提取方法”重构是否正确,重构之后是否产生了新的bug。
接下来我们针对两个新的方法创建两个测试方法,进行单元测试,把对结果检查的工作交给单元测试中的断言来做。
1. 我们在测试项目LeasePowerBankTest中找到UnitTest1.cs测试类文件,然后在此文件的顶部添加 如下代码语句,供测试项目调用。代码如下:
using LeasePowerBank;
对测试类的最低要求有:
1)任何包含要在“测试资源管理器”中运行的单元测试方法的类都需要有 [TestClass] 特性。
2)需要“测试资源管理器”识别的每个测试方法都必须具有 [TestMethod] 属性。
3)单元测试项目中可以具有不含 [TestClass] 特性的其他类,测试类中可以具有不含 [TestMethod] 特性的其他方法。 可以从测试方法中调用这些其他的类和方法。
在此过程中,编写单元测试方法以验证 Customer类的 GetAmount方法的行为。
我们的单元测试,至少需要检查两种行为:
如果计费金额小于应有金额,该方法会引发 ArgumentOutOfRangeException。
如果计费金额等于应有金额,则断言成功。
测试方法必须满足以下要求:
1)使用 [TestMethod] 特性进行修饰。
2)它将返回 void 。
3) 它不能含有参数。
2. 对GetAmount的单元测试方法代码如下:
[TestMethod]
public void ValidGetAmountTest()
{
double expected = 5;
//创建用户
var customer = new Customer("张三");
//创建充电宝
PowerBank regularPowerBank = new PowerBank("低-充电宝", PowerBank.LowTraffic);
//创建租赁数据
var rental1 = new Rental(regularPowerBank, 5);
// Act
decimal actual = customer.GetAmount(rental1);
// Assert
Assert.AreEqual(expected,actual,0.001, "总金额计算错误");
}
3. 对ValidGetFrequentRenterPointsTest的单元测试方法代码如下:
[TestMethod]
public void ValidGetFrequentRenterPointsTest()
{
int expected = 5;
//创建用户
var customer = new Customer("张三");
//创建充电宝
PowerBank regularPowerBank = new PowerBank("低-充电宝", PowerBank.LowTraffic);
//创建租赁数据
var rental1 = new Rental(regularPowerBank, 5);
// Act
int actual = customer.GetFrequentRenterPoints(0,rental1,5);
// Assert
Assert.AreEqual(expected, actual, 0.001, "积分计算错误");
}
4. 在Visual Studio 2019的菜单栏上找到 “生成” 菜单,选择 “生成解决方案” 。如下图。
5. 在Visual Studio 2019的菜单栏上找到“测试-->运行所有测试”菜单项。或者在“测试资源管理器中”选择 “在视图中运行所有测试”按钮, 以运行测试。如下图。
6.测试运行时,“测试资源管理器”窗口顶部的状态栏呈动态 。 测试运行结束时,如果测试方法全部通过,状态栏将变为绿色。如下图。
7. 我们将ValidGetAmountTest方法修改如下。
[TestMethod]
public void ValidGetAmountTest()
{
double expected = 6;
//创建用户
var customer = new Customer("张三");
//创建充电宝
PowerBank regularPowerBank = new PowerBank("低-充电宝", PowerBank.LowTraffic);
//创建租赁数据
var rental1 = new Rental(regularPowerBank, 5);
// Act
double actual = (double)customer.GetAmount(rental1);
// Assert
Assert.AreEqual(expected,actual,0.001, $"总金额计算错误,实际计算金额{actual},期望金额:{expected}");
}
8.在这种情况下,我们再次通过“测试-->运行所有测试”运行测试,结果有一个测试失败。如下图。在“测试资源管理器” 中选择该方法,可在“测试详细信息摘要”窗口查看详细信息。