web-dev-qa-db-ja.com

単体テストプロジェクトは、ターゲットアプリケーションのapp.configファイルをロードできますか?

App.configファイルを使用して構成プロパティを読み込む.NETアプリケーション(.exe)の単体テストを行っています。単体テストアプリケーション自体にはapp.configファイルがありません。

構成プロパティのいずれかを使用するメソッドを単体テストしようとすると、nullが返されます。これは、単体テストアプリケーションがターゲットアプリケーションのapp.configに読み込まれないためだと思います。

これをオーバーライドする方法はありますか、またはターゲットapp.configの内容をローカルapp.configにコピーするスクリプトを作成する必要がありますか?

This post kind-ofはこの質問をしますが、著者は実際に私とは異なる角度から見ています。

EDIT:ユニットテストにVS08チームシステムを使用していることに言及する必要があります。

143
Jordan Parmer

これを行う最も簡単な方法は、単体テストの展開セクションに.configファイルを追加することです。

これを行うには、ソリューションアイテムから.testrunconfigファイルを開きます。 [展開]セクションで、プロジェクトのビルドディレクトリ(おそらく.config)からの出力bin\Debugファイルを追加します。

展開セクションにリストされているものはすべて、テストが実行される前にテストプロジェクトの作業フォルダーにコピーされるため、構成に依存するコードは正常に実行されます。

編集:追加するのを忘れましたが、これはすべての状況で機能するわけではありません。そのため、ユニットテストの名前と一致するように出力.configの名前を変更する起動スクリプトを含める必要があります。

55
Jeromy Irvine

Visual Studio 2008では、app.configファイルを既存のアイテムとしてテストプロジェクトに追加し、リンクがコピーされないようにコピーとして選択しました。そうすれば、ソリューションに1つのコピーしかありません。いくつかのテストプロジェクトでは、非常に便利です。

Add Existing Item

Add As Link

92
Geoffroy Seive

Team System TestまたはNUnitを使用しているかどうかにかかわらず、ベストプラクティスは、テスト用に別のクラスライブラリを作成することです。 App/configをテストプロジェクトに追加するだけで、/をコンパイルすると、自動的にbinフォルダーにコピーされます。

コードが特定の構成テストに依存している場合、最初に書くテストでは、構成ファイルが使用可能であることを検証します(私が非常識ではないことを知っている):

<configuration>
   <appSettings>
       <add key="TestValue" value="true" />
   </appSettings>
</configuration>

そしてテスト:

[TestFixture]
public class GeneralFixture
{
     [Test]
     public void VerifyAppDomainHasConfigurationSettings()
     {
          string value = ConfigurationManager.AppSettings["TestValue"];
          Assert.IsFalse(String.IsNullOrEmpty(value), "No App.Config found.");
     }
}

理想的には、構成オブジェクトがクラスに渡されるようにコードを記述する必要があります。これにより、構成ファイルの問題と区別されるだけでなく、さまざまな構成シナリオのテストを作成することもできます。

public class MyObject
{
     public void Configure(MyConfigurationObject config)
     {
          _enabled = config.Enabled;
     }

     public string Foo()
     {
         if (_enabled)
         {
             return "foo!";
         }
         return String.Empty;
     }

     private bool _enabled;
}

[TestFixture]
public class MyObjectTestFixture
{
     [Test]
     public void CanInitializeWithProperConfig()
     {
         MyConfigurationObject config = new MyConfigurationObject();
         config.Enabled = true;

         MyObject myObj = new MyObject();
         myObj.Configure(config);

         Assert.AreEqual("foo!", myObj.Foo());
     }
}
53
bryanbcook

たとえば、Webアプリケーションとテストプロジェクトを含むソリューションがある場合は、おそらくテストプロジェクトでWebアプリケーションのweb.configを使用する必要があります。

これを解決する1つの方法は、web.configをコピーしてテストプロジェクトにし、app.configという名前に変更することです。

別のより良い解決策は、ビルドチェーンを変更し、web.configの自動コピーを作成して、プロジェクトの出力ディレクトリをテストすることです。これを行うには、「アプリケーションのテスト」を右クリックして、プロパティを選択します。これで、プロジェクトのプロパティが表示されます。 [ビルドイベント]をクリックし、[ビルド後の編集...]ボタンをクリックします。そこに次の行を書きます:

copy "$(SolutionDir)\WebApplication1\web.config" "$(ProjectDir)$(OutDir)$(TargetFileName).config"

OKをクリックします。 (テストするプロジェクト名としてWebApplication1を変更する必要がある可能性が最も高いことに注意してください)。 web.configへのパスが間違っていると、コピーが失敗し、ビルドが失敗したときにそれがわかります。

編集:

現在のプロジェクトからテストプロジェクトにコピーするには:

copy "$(ProjectDir)bin\WebProject.dll.config" "$(SolutionDir)WebProject.Tests\bin\Debug\App.Config"
20
Antti

これは少し古いですが、これに対するより良い解決策を見つけました。ここで選択した答えを試していましたが、.testrunco​​nfigはすでに廃止されているようです。

1.単体テストの場合、構成のラップはインターフェイス(IConfig)です

単体テストの場合、configは実際にはテストの一部ではないため、注入可能なモックを作成します。この例では、Moqを使用していました。

Mock<IConfig> _configMock;
_configMock.Setup(config => config.ConfigKey).Returns("ConfigValue");
var SUT = new SUT(_configMock.Object);

2.統合テストの場合、必要な構成を動的に追加します

Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
if(config.AppSettings.Settings[configName] != null)
{
    config.AppSettings.Settings.Remove(configName);
}
config.AppSettings.Settings.Add(configName, configValue);
config.Save(ConfigurationSaveMode.Modified, true);
ConfigurationManager.RefreshSection("appSettings");
7
MichaelChan

これはとても簡単です。

  • テストプロジェクトを右クリックします
  • 追加->既存のアイテム
  • [追加]ボタンの横に小さな矢印が表示されます
  • 構成ファイルを選択し、「リンクとして追加」をクリックします
5
Hari Das

NUnitを使用している場合は、 この投稿 をご覧ください。基本的に、app.configを.nunitファイルと同じディレクトリに置く必要があります。

4
Cory Foy

アプリケーションがAsp.net ConnectionStringなどの設定を使用している場合、属性HostTypeをメソッドに追加する必要があります。そうしないと、App.Configファイルがある場合でもロードされません。

[TestMethod]
[HostType("ASP.NET")] // will load the ConnectionString from the App.Config file
public void Test() {

}
2
Zyo

NUnitを使用し、プロジェクトディレクトリに、構成を変更するApp.Configのコピーがあります(例:テストデータベースにリダイレクトします...)。テストしたプロジェクトの同じディレクトリに配置する必要があり、問題ありません。

0

私はこれらの提案のいずれもnUnit 2.5.10で動作するように得ることができなかったので、nUnitのプロジェクト->編集機能を使用してターゲットにする構成ファイルを指定することになりました(他の人が。 nunitファイル自体)。これのプラス面は、構成ファイルにTest.config名を付けることができることです。これにより、構成ファイルの内容と理由がより明確になります。

0
Jane