App.configファイルを使用して構成プロパティを読み込む.NETアプリケーション(.exe)の単体テストを行っています。単体テストアプリケーション自体にはapp.configファイルがありません。
構成プロパティのいずれかを使用するメソッドを単体テストしようとすると、nullが返されます。これは、単体テストアプリケーションがターゲットアプリケーションのapp.configに読み込まれないためだと思います。
これをオーバーライドする方法はありますか、またはターゲットapp.configの内容をローカルapp.configにコピーするスクリプトを作成する必要がありますか?
This post kind-ofはこの質問をしますが、著者は実際に私とは異なる角度から見ています。
EDIT:ユニットテストにVS08チームシステムを使用していることに言及する必要があります。
これを行う最も簡単な方法は、単体テストの展開セクションに.config
ファイルを追加することです。
これを行うには、ソリューションアイテムから.testrunconfig
ファイルを開きます。 [展開]セクションで、プロジェクトのビルドディレクトリ(おそらく.config
)からの出力bin\Debug
ファイルを追加します。
展開セクションにリストされているものはすべて、テストが実行される前にテストプロジェクトの作業フォルダーにコピーされるため、構成に依存するコードは正常に実行されます。
編集:追加するのを忘れましたが、これはすべての状況で機能するわけではありません。そのため、ユニットテストの名前と一致するように出力.config
の名前を変更する起動スクリプトを含める必要があります。
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());
}
}
たとえば、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"
これは少し古いですが、これに対するより良い解決策を見つけました。ここで選択した答えを試していましたが、.testrunconfigはすでに廃止されているようです。
単体テストの場合、configは実際にはテストの一部ではないため、注入可能なモックを作成します。この例では、Moqを使用していました。
Mock<IConfig> _configMock;
_configMock.Setup(config => config.ConfigKey).Returns("ConfigValue");
var SUT = new SUT(_configMock.Object);
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");
これはとても簡単です。
NUnitを使用している場合は、 この投稿 をご覧ください。基本的に、app.configを.nunitファイルと同じディレクトリに置く必要があります。
アプリケーションがAsp.net ConnectionStringなどの設定を使用している場合、属性HostTypeをメソッドに追加する必要があります。そうしないと、App.Configファイルがある場合でもロードされません。
[TestMethod]
[HostType("ASP.NET")] // will load the ConnectionString from the App.Config file
public void Test() {
}
NUnitを使用し、プロジェクトディレクトリに、構成を変更するApp.Configのコピーがあります(例:テストデータベースにリダイレクトします...)。テストしたプロジェクトの同じディレクトリに配置する必要があり、問題ありません。
私はこれらの提案のいずれもnUnit 2.5.10で動作するように得ることができなかったので、nUnitのプロジェクト->編集機能を使用してターゲットにする構成ファイルを指定することになりました(他の人が。 nunitファイル自体)。これのプラス面は、構成ファイルにTest.config名を付けることができることです。これにより、構成ファイルの内容と理由がより明確になります。