他のキャラクターを攻撃するキャラクターなどを使ったロールゲームの開発を始めたとします。
TDDを適用して、Character.receiveAttack(Int)
メソッド内のロジックをテストするテストケースをいくつか作成します。このようなもの:
_@Test
fun healthIsReducedWhenCharacterIsAttacked() {
val c = Character(100) //arg is the health
c.receiveAttack(50) //arg is the suffered attack damage
assertThat(c.health, is(50));
}
_
receiveAttack
メソッドをテストする10のメソッドがあるとします。ここで、メソッドCharacter.attack(Character)
(receiveAttack
メソッドを呼び出す)を追加し、いくつかのTDDサイクルでそれをテストした後、決定を行います:Character.receiveAttack(Int)
はprivate
。
以前の10件のテストケースはどうなりますか?それらを削除する必要がありますか?メソッドpublic
を保持する必要がありますか(そうは思いません)?
この質問は、プライベートメソッドをテストする方法ではなく、TDDを適用する場合の再設計後にそれらを処理する方法についてです
TDDでは、テストは設計の実行可能なドキュメントとして機能します。デザインが変更されたので、当然、ドキュメントも変更する必要があります。
TDDでは、attack
メソッドが出現する可能性がある唯一の方法は、失敗したテストパスを作成した結果であることに注意してください。つまり、attack
は他のテストによってテストされています。つまり、間接的にreceiveAttack
はattack
のテストでカバーされます。理想的には、receiveAttack
を変更すると、attack
のテストの少なくとも1つが失敗するはずです。
そうでない場合、receiveAttack
には不要な機能が存在し、存在しなくなります。
したがって、receiveAttack
はattack
を通じてすでにテストされているため、テストを継続するかどうかは関係ありません。 Ifテストフレームワークを使用すると、プライベートメソッドを簡単にテストできます。ifプライベートメソッドをテストする場合は、保持できます。ただし、テストの適用範囲と信頼性を失うことなく、それらを削除することもできます。
メソッドがテストを必要とするほど複雑である場合、それはいくつかのクラスでパブリックでなければなりません。だからあなたはからリファクタリングします:
public class X {
private int complexity(...) {
...
}
public void somethingElse() {
int c = complexity(...);
}
}
に:
public class Complexity {
public int calculate(...) {
...
}
}
public class X {
private Complexity complexity;
public X(Complexity complexity) { // dependency injection happiness
this.complexity = complexity;
}
public void something() {
int c = complexity.calculate(...);
}
}
X.complexityの現在のテストをComplexityTestに移動します。次に、複雑さをあざけってX.somethingにテキストを送信します。
私の経験では、より小さなクラスとより短いメソッドに向けてリファクタリングすることには大きなメリットがあります。それらは理解しやすく、テストも簡単で、予想以上に再利用されることになります。
ReceiveAttackメソッドをテストする10のメソッドがあるとします。次に、Character.attack(Character)メソッド(receiveAttackメソッドを呼び出す)を追加し、いくつかのTDDサイクルでそれをテストした後、決定を行います。Character.receiveAttack(Int)はプライベートである必要があります。
ここで覚えておくべきことは、あなたが下している決定がAPIからメソッドを削除するであることです。後方互換性の礼儀は示唆するでしょう
APIがメソッドをサポートしなくなると、テストは削除または置換されます。その時点で、プライベートメソッドは実装の詳細であり、リファクタリングできるはずです。
その時点で、テストスイートが純粋にパブリックAPIを介して対話するのではなく、実装に直接アクセスする必要があるかどうかという標準的な質問に戻ります。プライベートメソッドは、置き換えることができるはずですテストスイートが邪魔にならない限り。したがって、私はそれと関連するテストがなくなることを期待します-廃止されるか、実装を個別にテスト可能なコンポーネントに移行します。