我正在编写香蕉图的模拟。目前,我有一个GameMaster
类来维护共同的作品集合。该deal(Player)
方法将一定数量的棋子发给该玩家。
我想为此编写单元测试。但是,此时我没有 getter,因此无法检查对象的状态。
为什么不添加吸气剂?我不想将代码添加到公共接口仅用于测试。现在,没有其他理由公开这些功能。
我应该在这里做什么?无论如何都要添加 getter,弄乱公共 API(或者希望将来需要它们)?放弃单元测试?(听起来是个坏主意。)
或者,这是否表明我的公共接口存在缺陷?
我正在编写香蕉图的模拟。目前,我有一个GameMaster
类来维护共同的作品集合。该deal(Player)
方法将一定数量的棋子发给该玩家。
我想为此编写单元测试。但是,此时我没有 getter,因此无法检查对象的状态。
为什么不添加吸气剂?我不想将代码添加到公共接口仅用于测试。现在,没有其他理由公开这些功能。
我应该在这里做什么?无论如何都要添加 getter,弄乱公共 API(或者希望将来需要它们)?放弃单元测试?(听起来是个坏主意。)
或者,这是否表明我的公共接口存在缺陷?
与其依赖 Player 的具体实例,不如将单元测试写入接口(或等效接口),并依赖模拟或其他交互来验证玩家不是处于正确的状态,而只是验证正确的调用 (从 GameMaster 类的角度来看。
如果在不依赖验证 Player 的最终状态的情况下无法验证 GameMaster 类的正确行为,则表明您的职责错位了。GameMaster 应该负责告诉 Player 发生了什么,而 Player 应该负责采取适当的行动。
这也是一个好处,因为这意味着 GameMaster 的测试将仅依赖于 GameMaster 类的行为,如果 Player 类改变其行为,则不需要触及。
避免为单元测试添加 getter。当您想添加一个 getter 时,请考虑使用交互测试(正如我刚刚描述的)而不是基于状态的测试。
验证一段代码是否有效的方法不止一种。我们大多数人想到的第一个是基于状态的测试(即,使用 getter 来验证对象的最终状态是否是您认为应该的状态)。但是,另一种验证代码是否有效的方法是使用基于行为或交互的测试。
Martin Fowler 有一篇关于这里区别的不错的文章
您应该测试内部使用这些状态保持变量的功能。如果没有公共功能正在使用它们,那么它们就是死代码。
我会说你的课可能做得太多了。听起来你让他们存储状态并做其他事情。
考虑什么会使它们更容易测试。如果将状态和逻辑分开,您将如何测试它们?而不是仅仅打电话
GameMaster gameMaster = new GameMaster;
playerOne.Score = gameMaster.ComputePlayerScore(newScore);
您将 GameState 的仅状态实例传递给 GameMaster 例程的构造函数:
GameState gameState = new GameState;
GameMaster gameMaster = new GameMaster(gameState);
playerOne.Score = gameMaster.ComputePlayerScore(newScore);
然后,您的单元测试例程可以传入他们需要的任何数据用于 gameState 和 newScore,并在 gameState 返回后检查结果。依赖注入是你的朋友。
您可以做的一件事是将您的主类子类化以提供用于测试的吸气剂。如果您有接口可以使用,这会更容易。
提供 getter 的子类化是一个半危险的提议。如果您只是为内部属性提供吸气剂,那么损害将是最小的,但您需要注意您正在测试实际类而不是派生版本。
我认为添加专门用于可测试性的代码没有任何问题。单元测试对于回归测试是无价的。
但是,它不应该影响您的公共 API 也是正确的。因此,我建议让 getter 受包保护,并将单元测试与Player
类放在同一个包中。(尽管在不同的源文件夹中,这样您就可以清楚地分离生产代码和测试代码。)
单元测试不会使您的代码更好,它们会使您的整个应用程序随着时间的推移随着更改和添加的功能而更加稳定。这就是为什么如果您的 GameMaster 类中没有公共 getter,则无需为单元测试创建它们。
没有吸气剂并不意味着你的界面是流畅的,测试驱动的开发理念是编写最少的代码来通过测试(来自需求),如果你不需要,你就不要写。打印,跟踪,日志将在单元测试消失后很长一段时间内出现(好吧,它们也将继续存在,但在许多情况下被过度使用和过度使用)
我应该在这里做什么?无论如何都要添加 getter,弄乱公共 API(或者希望将来需要它们)?
我没有得到这个回应。吸气剂如何“杂乱”?
你正在做测试驱动开发。设计是由绝对需要测试一切驱动的。
吸气剂不是“杂乱无章”的。它们是你测试事物的方式。
“放弃单元测试?”
我不认为这是一个好主意。