6

私はTDDの基本原則に精通しています。

  1. テストを書く、これらは実装がないため失敗します
  2. テストに合格するための基本的な実装を作成する
  3. コードをリファクタリング

ただし、インターフェイスと実装がどこに適合するかについては少し混乱しています。私は暇なときにSpringWebアプリケーションを作成しています。そして、銃を燃やすのではなく、インターフェイス/実装をもう少しうまくテストする方法を理解したいと思います。ここで作成したこの簡単なサンプルコードを見てください。

public class RunMe
{

    public static void main(String[] args)
    {
        // Using a dummy service now, but would have a real implementation later (fetch from DB etc.)
        UserService userService = new DummyUserService();
        System.out.println(userService.getUserById(1));
    }
}

interface UserService
{
    public String getUserById(Integer id);
}

class DummyUserService implements UserService
{
    @Override
    public String getUserById(Integer id)
    {
        return "James";
    }
}

私はUserServiceインターフェースを作成しました。最終的にはデータベースにクエリを実行する実際の実装がありますが、アプリケーションを稼働させるために、DummyUserService今のところ静的データを返すだけの実装に置き換えました。

質問:上記のテスト戦略をどのように実装できますか?

と呼ばれるテストクラスを作成し、それDummyUserServiceTestを呼び出すgetUserById()と返されることをテストできますJames。時間の無駄ではないにしても、かなり単純に見えます(?)。

その後、データベースからユーザー名を返すテストクラスRealUserServiceを作成することもできます。getUserById()これは私を少し混乱させる部分です。そうすることで、これは本質的に単体テストの境界を超えて、(DBにヒットした)統合テストのようになりませんか?

質問(少し改善されました):ダミー/スタブされたインターフェースと実際の実装を使用する場合、どの部分を単体テストする必要があり、どの部分を安全にテストしないでおくことができますか?

私は昨夜このトピックについてグーグルで数時間を過ごし、TDDとは何かに関するチュートリアル、またはJUnitの使用方法の例をほとんど見つけましたが、実際に何をテストすべきかをアドバイスする領域には何もありませんでした。しかし、私が十分に検索しなかったか、正しいものを探していなかった可能性は完全にあります...

4

3 に答える 3

4

ダミーの実装をテストしないでください。本番環境では使用されません。それらをテストすることは実際には意味がありません。

実際のUserService実装がデータベースにアクセスし、そのIDでユーザー名を取得する以外に何もしない場合、テストはそれが実行され、正しく実行されることをテストする必要があります。必要に応じて統合テストと呼びますが、それでも、作成して自動化する必要があるテストです。

通常の戦略は、テストの@Before注釈付きメソッドで最小限のテストデータをデータベースに入力し、データベースに存在するIDについて、対応するユーザー名が返されることをテストメソッドで確認することです。

于 2012-05-12T09:44:59.177 に答える
3

最初にこの本を読むことをお勧めします:SteveFreemandとNatPryceによるテストによって導かれる成長するオブジェクト指向ソフトウェア。TDDに関連するあなたの質問や他の多くの質問に答えます。

特定のケースRealUserServiceでは、実際のDBクエリを作成するDBアダプターを使用して構成可能にする必要があります。データの永続性ではなく、サービス自体がサービスを提供します。本を読んでください、それは大いに役立ちます:)

于 2012-05-14T17:28:10.220 に答える
0

JBの答えは良いものです。私が使った別のテクニックを捨てると思いました。

元のテストを開発するときは、そもそもわざわざスタブアウトしないでくださいUserService。実際、先に進んで本物を書いてください。KentBeckの3つのルールに従って続行します。

1)それを機能させる。2)正しくする。3)速くします。

コードには、IDによる検索が機能することを確認するテストが含まれます。JBが述べたように、あなたのテストはこの時点で統合テストと見なされます。それらが合格すると、ステップ1が正常に達成されます。次に、設計を確認します。正しいですか?デザインの匂いを微調整し、リストからステップ2を確認します。

ステップ3では、このテストを高速にする必要があります。統合テストは遅く、すべてのトランザクション管理とデータベース設定でエラーが発生しやすいことは誰もが知っています。コードが機能することがわかったら、通常、統合テストに煩わされることはありません。この時点で、ダミーサービスを導入して、統合テストを効果的に単体テストに変えることができます。データベースにまったく触れないようになったので、このテストが高速になったため、リストからステップ3をチェックできます。

それで、このアプローチの問題は何ですか?まあ、多くの人は私がまだデータベースに裏打ちされたのテストが必要だと言うでしょうUserService。私は通常、統合テストをプロジェクトに配置し続けません。私の意見では、これらのタイプのテストは遅く、もろく、ほとんどのプロジェクトで自分たちで支払うのに十分な論理エラーをキャッチしていません。

お役に立てば幸いです。

ブランドン

于 2012-05-14T11:36:07.187 に答える