16

Microsoft の単体テスト フレームワークを使用して単体テストを行いたいクラス ライブラリがあります。テストしたいクラスのいくつかは、アプリケーション設定を使用して構成されています。これらの設定は、Settings.settingsアプリケーション スコープと適切なデフォルト値を持つファイル内で定義されます。ライブラリがアプリケーションによって使用される場合、これらの設定はファイルでオーバーライドできApp.Configます。そうでない場合は、デフォルト値が使用されます。それがまさに私が望んでいる方法です。

いくつかのテスト ケースでは、設定値の特別な組み合わせをテストしたいのですが、単体テスト コードからテスト対象のクラスに表示される値を変更する方法がわかりません。これらの設定には、コード生成クラスの属性からロードされたデフォルト値が常に含まれます。

ライブラリ クラスでは、次のような設定にアクセスします。

var mySetting1 = Settings.Default.MySetting1;
var mySetting2 = Settings.Default.MySetting2;

テスト対象のクラスが設定にアクセスする前に、単体テストでこれらの設定を変更するにはどうすればよいですか? 単体テストで内部設定クラスにアクセスできるようにしても、設定にはアプリケーション スコープがあり、設定クラスの読み取り専用プロパティであるため、問題は解決しません。

4

2 に答える 2

20

および関連するクラスに飛び込んだ後、ApplicationSettingsBase私は自分の問題に対するこの解決策を思いつきました。特に美しいわけではありませんが、それは確かに仕事を成し遂げます。

コードで生成された設定クラスは、クラスライブラリプロジェクトの内部にあり、単体テストプロジェクトからアクセスできる必要があります。クラスライブラリプロジェクトに[assembly: InternalsVisibleTo("UnitTestAssemblyName")]属性を追加します。AssemblyInfo.cs

値にアクセスすると、設定は設定クラスの属性から遅延ロードされます。最初のステップは、設定の「ダミー」読み取りを実行して、この遅延読み込みを強制することです。単体テストでは、あるテストで設定値が変更されて別のテストに影響を与えないようにする必要があるため、遅延ロードする前に設定を「リセット」する必要があります。Reload()これは、メソッドを使用して実行できます。このコードは、テスト初期化メソッドに配置されます。

Settings.Default.Reload();
var dummy = Settings.Default.MySetting1;

基になる値が存在し、各テストメソッドで設定できます。コードで生成されたゲッターがキャストを行うため、正しいタイプを使用することを忘れないでください。

Settings.Default.PropertyValues["MyStringSetting1"].PropertyValue = "Foobar";
Settings.Default.PropertyValues["MyDoubleSetting2"].PropertyValue = 3.1416D;
于 2010-09-17T10:45:59.050 に答える
5

クラスの周りにラッパー クラスを作成し、Settingsそのラッパーを渡します。次に、設定クラスを簡単にモックできます。

私が思いつくことができる唯一の他のことは、設定ファイルにすべての設定を反映するインターフェースを実装させるという、わずかに軽量で簡単にモックできるオプションです。呼び出し元にとってはそれほど違いはありませんが、新しい設定を追加するときに行う配管作業が少なくなります。

どちらも素晴らしいものではなく、自動生成されたコードに対してそれを行わなければならないのは面倒ですが、設定ファイルへの依存を本当に削除したいのかどうかを知る限り、それが私たちが行き詰まっているようです.

たとえば、文字列の Application 設定と int の User 設定を含む設定ファイルの場合:

internal sealed partial class Settings : IMySettings {

    /*
     * here be auto-generate code (and dragons!)
     */
}

internal interface IMySettings
{
    string ApplicationSetting
    {
        get;
    }

    string UserSetting
    {
        get;
        set;
    }
}
于 2010-09-15T15:28:04.110 に答える