本系列第二篇文章演示了如何在家庭自动化系统 (HAS) 应用程序中实现用于确定白天或夜间的逻辑,该应用程序控制猫门的锁定和解锁。 这第三篇文章解释了如何编写代码以在应用程序中使用该逻辑,该应用程序在夜间锁定门并在白天解锁门。
提醒一下,请按照此处的说明进行设置,以便使用 .NET xUnit.net 测试框架进行后续操作。
在夜间禁用猫活板门
假设猫门是一个复杂的物联网 (IoT) 产品,它具有 IP 地址,可以通过向其 API 发送请求来访问。为了简洁起见,本系列不介绍如何对 IoT 设备进行编程;相反,它模拟了该服务,以将重点放在测试驱动开发 (TDD) 和变异测试上。
首先编写一个失败的单元测试
[Fact]
public void GivenNighttimeDisableTrapDoor() {
var expected = "Cat trap door disabled";
var timeOfDay = dayOrNightUtility.GetDayOrNight(nightHour);
var actual = catTrapDoor.Control(timeOfDay);
Assert.Equal(expected, actual);
}
这描述了一个全新的组件或服务 (catTrapDoor)。该组件(或服务)具有根据当前时间控制活板门的能力。现在是时候实现 catTrapDoor 了。
要模拟此服务,您必须首先使用接口描述其功能。在 app 文件夹中创建一个新文件,并将其命名为 ICatTrapDoor.cs(按照惯例,接口名称以大写字母 I 开头)。将以下代码添加到该文件
namespace app{
public interface ICatTrapDoor {
string Control(string dayOrNight);
}
}
此接口不具备运行能力。它仅仅描述了您在构建 CatTrapDoor 服务时的意图。接口是创建您正在使用的服务的抽象的好方法。在某种程度上,您可以将此接口视为 CatTrapDoor 服务的 API。
要实现 API,请在 app 文件夹中创建一个新文件,并将其命名为 FakeCatTrapDoor.cs。将以下代码输入到类文件中
namespace app{
public class FakeCatTrapDoor : ICatTrapDoor {
public string Control(string dayOrNight) {
string trapDoorStatus = "Undetermined";
if(dayOrNight == "Nighttime") {
trapDoorStatus = "Cat trap door disabled";
}
return trapDoorStatus;
}
}
}
这个新的 FakeCatTrapDoor 类实现了接口 ICatTrapDoor。它的 Control 方法接受字符串值 dayOrNight,并检查传入的值是否为“Nighttime”。如果是,它会将 trapDoorStatus 从“Undetermined”修改为“Cat trap door disabled”,并将该值返回给调用客户端。
为什么称之为 FakeCatTrapDoor?因为它不是真实猫活板门的表示。这个“fake”只是帮助您理清处理逻辑。一旦您的逻辑严密,fake 服务就会被真实服务取代(此主题保留给集成测试学科)。
完成所有实现后,所有单元测试在运行时都会通过
Starting test execution, please wait...
Total tests; 3. Passed: 3. failed: 0. Skipped: 0.
Test Run Successful.
Test execution time: 1.3913 Seconds
在白天启用猫活板门
现在是时候看看我们用户故事中的下一个场景了
场景 #2:在白天启用猫活板门
- 假设时钟检测到白天
- 当时钟通知 HAS 时
- 然后 HAS 启用猫活板门
这应该很容易,只是第一个场景的反面。首先,编写失败的测试。将以下单元测试添加到 unittest 文件夹中的 UnitTest1.cs 文件中
[Fact]
public void GivenDaylightEnableTrapDoor() {
var expected = "Cat trap door enabled";
var timeOfDay = dayOrNightUtility.GetDayOrNight(dayHour);
var actual = catTrapDoor.Control(timeOfDay);
Assert.Equal(expected, actual);
}
当将“Daylight”状态发送到 catTrapDoor 服务时,您可以期望收到“Cat trap door enabled”通知。当您运行单元测试时,您会看到您期望的结果,即按预期失败
Starting test execution, please wait...
[Xunit unittest.UnitTest1.UnitTest1.GivenDaylightEnableTrapDoor [FAIL]
Failed unittest.UnitTest1.UnitTest1.GivenDaylightEnableTrapDoor
[...]
单元测试期望收到“Cat trap door enabled”通知,但实际上收到的通知是猫活板门状态为“Undetermined”。太棒了;现在是时候解决这个小故障了。
向 FakeCatTrapDoor 添加三行代码即可解决问题
if(dayOrNight == "Daylight") {
trapDoorStatus = "Cat trap door enabled";
}
再次运行单元测试,所有测试都通过
Starting test execution, please wait...
Total tests: 4. Passed: 4. Failed: 0. Skipped: 0.
Test Run Successful.
Test execution time: 2.4888 Seconds
太棒了!一切看起来都不错,所有单元测试都呈绿色,您拥有一个坚如磐石的解决方案。谢谢你,TDD!
别高兴得太早!
经验丰富的工程师不会相信该解决方案坚如磐石。为什么?因为该解决方案尚未经过变异。要深入了解什么是变异以及为什么它很重要,请务必阅读本系列的最后一篇文章。
评论已关闭。