単体テスト:「リファクタリングしていて、共同編集者がいない場合、コードのにおいがします」?


9

私はロイ・オセロベによるユニットテストの芸術を読んでいます。私はセクション7.2にいます。ここでは、作成者がコードのにおいについてこのメモを持っています。

注:外部テストから見えるように内部状態をリファクタリングする場合、それはコードのにおい(コードの設計またはロジックに問題がある可能性がある兆候)と見なすことができますか?共同編集者を公開するためにリファクタリングしているときは、コードのにおいではありません。リファクタリングを行っていて、共同編集者がいない場合は、コードのにおいです(したがって、何もスタブしたりモックしたりする必要はありません)。

編集:著者が「共同編集者」によって意味するのは依存関係です。彼の依存関係の例には、データベースにアクセスするクラスや、OSのファイルシステムにアクセスするクラスがあります。ここで、彼はスタブを定義し、コラボレーターという言葉を使い始めます。

スタブは、既存の制御置換である依存性(または 共同編集システムにおいて)。

作者にはこのコードの匂いの例はなく、これがどのように見えるか理解/描写するのに苦労しています。誰かがこれをもう少し説明して、おそらく具体的な例を提供できますか?


ここでの混乱は「コラボレーター」という言葉に由来すると思います。私は彼がこの文脈で何を意味するのかよくわからないことを認めなければなりません。
rossipedia 2012

@ブライアン・ロス、私は著者が「コラボレーター」という言葉をどのように使用するかで投稿を更新しました。ありがとう!
プログラマー

回答:


3

これは著者がやろうとしていることだと思います。

私のコードサンプルでは、​​出力ウィンドウに開始時間と停止時間を加えたタイミングウィンドウがあります。その目的は、24時間の期間にわたって出力ウィンドウを描画することです。開始時刻が停止時刻よりも大きい場合、しわが追加されます。これは、真夜中のタイミングウィンドウであるためです。

プライベート変数を公開せずにオブジェクトを完全に実行する単体テストを作成できます。これらのプライベートブールとタイムスパンは、ユニットテストのために内部を公開するときに彼が参照している共同作業者です。本によると、それらは共同作業者なので、これらの内部を公開することはコードの匂いではありません。

double outputを公開することは、コラボレーターではないため、コードのにおいにGetOutputなります。これは、返すべきものを決定するための条件付きロジックを含む、クラス自体によって明示的に隠されている要素です。

ブール値/タイムスパンを掘り下げると、単体テストがより包括的になります。彼はこれが良いと言います。
ダブルoutputを掘り下げるには、ユニットテストで何GetOutputが行われているかを反映する追加のロジックが必要です。これは彼が言及しているコードのにおいでしょう。

パブリッククラスTimeWindow
{
  プライベートbool isConst;
  プライベートbool spansMidnight;
  プライベートTimeSpan start1;
  プライベートTimeSpan stop1;
  プライベートTimeSpan start2;
  プライベートTimeSpanストップ2;
  プライベートダブル出力。

  public TimeWindow(double out、TimeSpan start、TimeSpan stop)
  {
    出力=出力;

    if(start == stop)
      isConst = true;
    else if(start> stop)
    {
      spansMidnight = true;
      start1 =真夜中;
      stop1 =停止。
      start2 =開始;
      stop2 =真夜中;
    }
    そうしないと 
    {
      start1 =開始;
      stop1 =停止。
    }
  }

  public double GetOutput(TimeSpan time)
  {
    //何をどのように返すかに関するロジック
    ...
    出力を返す;
  }

}

0

ドメインクラスがあり、このドメインクラスがリポジトリを使用して永続性レイヤーを直接認識しているとしましょう。これは、ドメインクラスで動作するオブジェクトが変更を永続化するために呼び出すインスタンスレベルの「保存」メソッドを公開するために使用します。メカニズムの知識を必要とせずに作成されます(これが「良い」設計であるかどうかは別の日の議論です)。クラスをリファクタリングしてこのリポジトリをプロパティやコンストラクタの引数として公開し、モックされたリポジトリを渡して適切な呼び出しが行われるようにすることは、通常、テストだけでなく一般的なメンテナンス性にも優れています。

これはドメインクラスであり、状態データを持っています。少しの間、ステートフルプロパティの1つにバッキングフィールドがあり、プロパティアクセサーが現在の入力に基づいて新しい入力が有効であることをテストするとします(新しい値が古い値よりも小さくなることはありません)。この検証をテストする必要がありますが、そのためには、バッキングフィールドにアクセスして初期値を設定してから上書きを試みる必要があることがわかります。これは危険信号です。テストは、バッキングフィールドにアクセスする必要がある(実装の詳細である場合、消費者はすべきで、これまでテストのためにオブジェクトを一貫性のある状態にするために、それがそこにあることを知る必要があります。次に、本番用コードで一貫性のあるオブジェクトを取得するにはどうすればよいですか テストで行うのと同じことを本番コードで実行する方法がある場合、テストはおそらくその方法を模倣する必要があります。プロダクションコードがオブジェクトをこの状態にする有効な方法がない場合、なぜこのシナリオをテストするのですか?

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