我进退两难,是否要为重构另一种方法的产物的方法编写测试。
第一个问题,考虑这个情节。
class Puzzle(
val foo: List<Pieces>,
val bar: List<Pieces>
) {
init {
// code to validate foo
// code to validate bar
}
}
我在这里验证构造对象时的参数。此代码是 TDD 的结果。但是对于 TDD,我们编写了 fail_test -> pass test -> refactor
,在重构时我将验证器方法转移到了辅助类 PuzzleHelper
。
object PuzzleHelper {
fun validateFoo() {
...
}
fun validateBar() {
...
}
}
在这种情况下,我还需要测试 validateFoo
和 validateBar
吗?
第二个问题
class Puzzle(
val foo: List<Pieces>,
val bar: List<Pieces>
) {
...
fun getPiece(inPosition: Position) {
validatePosition()
// return piece at position
}
fun removePiece(inPosition: Position) {
validatePosition()
// remove piece at position
}
}
object PuzzleHelper {
...
fun validatePosition() {
...
}
}
还需要为getPiece
和removePiece
编写涉及位置验证的测试吗?
我真的很想熟练使用 TDD,但不知道如何开始。现在我终于一头扎进去了,不在乎前面是什么,我只想要产品质量。希望早日听到您的启迪。
最佳答案
当我们进入 Red -> Green -> Refactor
循环的重构阶段时,我们不应该添加任何新行为。这意味着所有代码都已经过测试,因此不需要新的测试。您可以通过更改重构代码轻松地验证您是否已完成此操作,并观察它是否未通过测试。如果没有,则说明您添加了不应该添加的内容。
在某些情况下,如果在其他地方重用提取的代码,将测试转移到重构代码的测试套件可能是有意义的。
至于第二个问题,这取决于你的设计,以及一些你的代码中没有的东西。例如,我不知道如果验证失败你想做什么。您必须为这些情况添加不同的测试,以防每种方法的验证失败。
我想指出的一件事是,将方法放在静态对象中(类函数、全局函数,无论您想如何调用它)都会使测试代码变得更加困难。如果您想在忽略验证时测试您的类方法(让它始终通过),您将无法做到这一点。
我更喜欢创建一个作为构造函数参数传递给类的协作者。所以你的类现在有一个 validator: Validator
并且你可以在测试中传递任何你想要的东西。 stub 、真实的东西、模拟等。
关于testing - TDD 单元测试子方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56495397/