我最近加入了一家他们使用TDD的公司,但我仍然不清楚,例如,我们有一个测试:
[TestMethod]
public void ShouldReturnGameIsRunning()
{
var game = new Mock<IGame>();
game.Setup(g => g.IsRunning).Returns(true);
Assert.IsTrue(game.Object.IsRunning);
}
Run Code Online (Sandbox Code Playgroud)
它的目的是什么?据我了解,这不测试任何东西!我之所以这么说是因为它嘲笑一个界面,并说,对于IsRunning,它返回true,它永远不会返回一个不同的值......
我可能错了,因为每个人都说这是一个很好的做法等等......或者这个测试是错的?
此测试超出了接口,并验证接口是否公开了名为的布尔getter IsRunning.
这个测试可能是在interface现有的之前编写的,可能在任何具体的类IGame存在之前.我想,如果项目有任何成熟度,那么还有其他测试可以运用实际的实现并验证该级别的行为,并且可能在更传统的隔离主义上下文中使用模拟,而不是扼杀理论形状.
这些测试的价值在于它迫使人们思考如何使用形状或对象."我不知道游戏究竟会做什么,但我确实知道我要检查它是否正在运行......".因此,这种测试方式更多的是推动设计决策,以及验证行为.
这不是地球上最有价值的测试,但在我看来是有用的.
编辑:昨晚我在火车上打字时我正在火车上,但我想直接在答案中解答安德鲁惠特克的评论.
有人可能会说,界面本身的签名足以执行所需的合同.但是,这实际上取决于您如何处理接口以及最终如何验证您要测试的系统.
明确说明此功能作为测试可能有实际价值.您明确验证这是一个所需的功能IGame.
让我们看一个用例,让我们说作为设计师你知道你想公开一个公共getter IsRunning,所以你把它添加到界面.但是让我们说另一个开发人员得到这个并看到一个属性,但是在代码中的任何其他位置都没有看到它的任何用法,人们可能会认为它有资格删除(或删除代码腐烂,这通常是一件好事)没有伤害.然而,该测试的存在明确指出应该存在这种适当性.
如果没有这个测试,开发人员可以修改接口,删除实现,项目仍然可以正常编译和运行.直到很久以后,有人可能会注意到界面已被更改.
通过此测试,即使看起来好像没有人使用它,您的测试套件也会失败.测试的自我记录性质告诉你,ShouldReturnGameIsRunning()如果IGame真的应该暴露一个IsRunninggetter ,那至少应该产生一个对话.