唯一のロジックがガードである単体テストメソッドは便利ですか?


12

次のような方法があるとします。

public void OrderNewWidget(Widget widget)
{
   if ((widget.PartNumber > 0) && (widget.PartAvailable))
   {
        WigdetOrderingService.OrderNewWidgetAsync(widget.PartNumber);
   }
}

私のコードにはそのようなメソッドがいくつかあります(非同期Webサービス呼び出しの前半分)。

それらを単体テストでカバーすることが有用かどうかを議論しています。はい、ここにはロジックがありますが、それはガードロジックにすぎません。(つまり、Webサービスの呼び出しを許可する前に、必要なものがあることを確認します。)

私の一部は、「あなたはそれらをユニットテストできることを確認しますが、それは時間の価値がありません」と言います(私はすでに予定より遅れているプロジェクトにいます)。

しかし、私の反対側は、もしあなたがそれらを単体テストしないで、誰かが衛兵を変えれば、問題があるかもしれないと言います。

しかし、私の最初の部分は、誰かがガードを変更した場合、あなたは彼らのためにもっと仕事をしているだけだと言います(ガードとガードのユニットテストを変更しなければならないからです)。

たとえば、私のサービスがウィジェットの可用性をチェックする責任を負う場合、そのガードをこれ以上望まないかもしれません。単体テスト中の場合は、2つの場所を変更する必要があります。

私は両方の面で賛否両論を見ています。だから私は他の人が何をしたかを尋ねると思った。


17
あなたはメンテナーのために「より多くの仕事」をしているのではありません。ロジックを変更する場合、対応する単体テストを変更する必要があります。それが動作する方法です。あなたの短所は見当たりません。もしあなたのユニットテストが変更を必要としなかったら、それは何もテストしていませんよね?同様に、単体テストが有用かどうか疑問に思うかもしれません。
アンドレスF.

9
これはトピックから外れていますが、パーツ番号が0以下の場合、またはパーツが利用できない場合、例外をスローするようにロジックを変更します。私の意見では、誰かがそのメソッドを偽のウィジェットで、静かに別の問題を隠しています。
マシュー

2
@マシュー非常に良い点。この機能があります。命名は、それが何かを注文するつもりであることを伝えます。そして、それはそうではありませんが、あなたが内部と同じロジックを適用しない限り、あなたは決して知りません。それはDRYを侵害します。言い換えれば、デザインがより正確になるように変更された場合、この質問はそもそも尋ねられなかったでしょう。
stijn

2
but it is not worth the time" (I am on a project that is already behind schedule).私たちはソフトウェア開発者です。私たちが予定通りにいるのは、私たちが死んでいるときだけです:)
maple_shaft

回答:


26

私の一部は、「あなたはそれらをユニットテストできることを確認しますが、それは時間の価値がありません」と言います(私はすでに予定より遅れているプロジェクトにいます)。

非常に短い3つのテストです。あなたは自分自身に質問するのに多くの時間を費やしました。

しかし、私の反対側は、もしあなたがそれらを単体テストしないで、誰かが衛兵を変えれば、問題があるかもしれないと言います。

こちら側を聞いてください。

しかし、私の最初の部分は、誰かがガードを変更した場合、あなたは彼らのためにもっと仕事をしているだけだと言います(ガードとガードのユニットテストを変更しなければならないからです)。

あなたのメンテナーがTDDナッツであるなら、あなたはそれらをより難しくしている。関連する変更やテストの追加がなくても変更を加えると、一生懸命考えなければなりません。実際、テストを追加してから変更を加えます。

あなたの最初の部分は明らかに間違っています。2番目の部分の背面を軽くたたいて、それについて考えるのを止めます。


私もあわやの答えを書いていても簡潔のため1
ジミー・ホッファ

3
+1。はい。要件が変更された場合、いくつかのテストを調整する必要があります。
オリビエジャコット-デスコンブ

あなたの言うことは好きですが、この種の呼び出しの多くのインスタンスがコードにあります(非同期呼び出しの前半)。したがって、3つの単体テストだけではありません。それでも、それが「正しい」方法であるなら、私はそれらを終わらせたいです。
ヴァッカーノ

@Vaccano:記述しなければならないものが多いほど、テストの対象とならない論理パスが増え、それらを記述する必要性が高まります。
pdr

9

ガードロジックと実際の順序付けが別々の方法である場合、単体テストが簡素化されます。

ではWidgetクラス

public bool IsReadyForOrdering { get { return PartNumber > 0 && PartAvailable; } }

または同等のメソッドをどこかに

public bool IsWidgetReadyForOrdering(Widget widget)
{
    return widget.PartNumber > 0 && widget.PartAvailable;
}

注文方法

public void OrderNewWidget(Widget widget)
{
   if (IsWidgetReadyForOrdering(widget)) {
        WigdetOrderingService.OrderNewWidgetAsync(widget.PartNumber);
   }
}

テストIsWidgetReadyForOrderingが簡単になりました。もう長い間考えないでください。試して!


1
Oof、プロパティのステートフルロジック。メソッドである必要があり、そのシンプルさのためにPartNumber、PartAvailableを取る必要があります。パブリックAPIの一部である必要はなく、プロパティである必要がない場合は、保護します。また、一般的には同意しません。メソッド内のガードロジックはまったく問題ありません。私の目には、このメソッドは非常に小さいため、クラスを汚染して既に小さなメソッドを小さくしているだけです。この場合、反復ロジックである場合にのみ、クラスに追加します。
ジミー・ホッファ

1
まず、これは質問に答えません。第二に、それは真実ではありません。どちらの方法でも3つのテストを作成する必要があります。第三に、呼び出しコードに実装の詳細を不必要に公開します。
pdr

8
@JimmyHoffa:そのプロパティのステートフルロジックはどこにありますか?実際、この例は、状態変化ロジック(OrderNewWidget)を非状態変化ロジック(ReadyForOrdering)から分離する方法を示しています。そして、私はあなたが述べているように、その小さな関数を抽出してもコードを改善し、悪化させないことを強く信じています。+1。
ドックブラウン

2
メソッドOrderNewWidgetは引数をWidget持っているため、おそらく以外のクラスにありWidgetます。メソッドには戻り値がないため、テストは明確ではありません。呼び出しWigdetOrderingServiceを追跡する-mock を挿入する必要がありOrderNewWidgetAsyncます。
オリビエジャコット-デスコンブ

2
@JimmyHoffa:実際には、「ステートレス」の定義はC#の「静的」を意味します。したがって、あなたが言うことは「プロパティはオブジェクトの状態にアクセスすべきではない」ということです。しかし、愚かなゲッターでさえも状態変数にアクセスするので、それは「静的プロパティのみを書き込む」ことを意味します-これはあまり意味がないようです。
ドックブラウン

6

単体テストのスケジュールに時間がないが、しっかりしたQAの使用に時間を割くことができる場合、そのQA時間の一部を盗んで単体テストを書くことができるかどうか、またはQA期間の一部を費やすことができるかどうかを尋ねますユニットテストを実行するか、ユニットテストされていないコードを処理します。残念ながら、不動のスケジュールは譲歩するか、自分自身を死に至らしめることを余儀なくされます。その期間システムを正しく維持する。

とはいえ、ガードステートメントをテストするという一般的な質問には、はい!ガードステートメントを絶対にテストしてください!これらは、そのメソッドの動作の重要な部分であり、あなたはバグ修正をしている誰かの誤解何かを知りたいと、あなたのガードを削除または変更していないだろう&&||、あなたでしょうか?ユニットテストは、a)実際にガードのロジックを正しく取得し、b)何らかの理由でユニットテストを実行するように指示するユニットテストを実行するときに、文句を言わずに後で誰もそのロジックを壊さないことを確認します。


0

上記のいくつかの優れた回答がありますが、それらのポイントは非常に重要です。しかし、見逃されているように見えるのは、あなたが包括的なユニットテストのセットを持っているということです。彼らはコードの非常に詳細な仕様のように読みます。コードが非常に簡単であるために検証のテストを省略すると、コードがどのように間違っているかを確認するのが難しいため、仕様の一部が欠落しています。これらのテストが見落とされていたチームに入った場合、実際にはあなたのサービスがその引数を検証していないと思います。


-5

コードはコードです。テストするときは、100%のカバレッジを得るようにしてください。それが重要でなければ、そこにはないでしょう。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.