2

ApplicationShouldBeInstalled(app)正しく動作していることを確認するために呼び出す単体テストがあります。以下の実際の製品コードもそのメソッドを呼び出しているため、誤ってアプリをインストールすることはありません。ただし、開発者がチェックが行われたコード行を削除することを妨げるものは何もありません。ApplicationShouldBeInstalled(app)テストはメソッドではなくメソッドをテストしているため、私の単体テストはそれをキャッチしませんInstallApplications()

InstallApplications()アプリケーションをインストールしようとするため、テスト コードから呼び出すことはできません。InstallApplication(app)インターフェイスでモックできる別のクラスではなく、同じクラスのメソッドです。InstallApplications() が常にそのチェックを実行するようにする方法はありますか? 別のクラスに移動してモックできると思いApplicationShouldBeInstalled(app)ますが、テスト/モックのためだけにコードを移動しています。より良い方法はありますか?

public void InstallApplications()
{
    foreach (App app in this._apps)
    {
        if (!ApplicationShouldBeInstalled(app)) { continue; }

        InstallApplication(app);
    }                       
}

モッキングオプションは次のようになります。Containerライブで実行すると実際の実装が返され、テストを実行するとモックが返されます。

public void InstallApplications()
{
    foreach (App app in this._apps)
    {
        if (!ApplicationShouldBeInstalled(app)) { continue; }

        Container.Resolve<IInstaller>().InstallApplication(app);
    }                       
}
4

2 に答える 2

2

はい、アプリケーションをインストールするかどうかのポリシーを制御するコードを、インストールを処理するコードから削除します。これにより、両方のコードを分離してテストし、それぞれが必要なことを行っているという確信を得ることができます。ここに 3 人の協力者がいるところまで行きます。ループを制御するコード、ポリシーに対する検証を制御するコード、最後にインストールを実行するコードです。独立してテスト可能で、検証が容易な 3 つの部分。

foreach (var app in this._apps)
{
     if (!applicationInstallationPolicyProvider.CanInstall(app)) // can be mocked away
     {
          continue;
     }

     applicationInstaller.Install(app); // can also be mocked away
}

あなたにとって重要なのは、「インストールコードをテストで実行できない」という質問で言ったときだと思います。ただし、必要に応じてループが実際にインストール コードを呼び出すことを確認することが重要です。あなたが私が好むかもしれない程度に取るかどうかにかかわらず、それはすでにそれを分離しようとする十分な動機になるはずです.

于 2013-02-14T19:57:52.020 に答える
1

それをインターフェイスに抽出すると、クラスに属するコードは実際には削除されません。クラスにメンバーを実装する必要があります。インターフェイスを使用する主な利点は、実際に機能を変更しないようにインターフェイスをモックできることです。インターフェイスをモックしてから、特定のメソッドが実際に期待どおりに動作していることを確認します。

余談ですが、メモリ内にオブジェクトのインスタンスを常に作成しないように、依存性注入を使用することもできます。

于 2013-02-14T19:58:44.310 に答える