2011-10-01 261 views
5

Tests.dllというアセンブリでC#アプリケーションのNUnitテストを分離しました。関連する構成ファイルの名前はTests.dll.configです。これは、アプリの実際の設定ファイルではなく、Nunitが使用するものです。これは、(多くのより多くがある場合にのみ設定オプションのカップルを示す)次のようになります。単体テスト用のapp.configファイルの操作

<?xml version="1.0" encoding="utf-8"?> 

<configuration> 
    <appSettings> 
    <add key="useHostsFile" value="true" /> 
    <add key="importFile" value="true" /> 

    </appSettings> 
</configuration> 

は、私のアプリを徹底的にテストされていることを確認するために私はテストの間に設定オプションを変更する必要があります。 私はいくつかのテストを実行した後、新しい設定値をファイルに追加し、後続のテストでこれらを使用したいと思います。これを追加するにはどのようなコードが必要でしょうか?

+0

ユースケースをよりよく説明できますか?実行時にtests.dll.configを変更する必要があるのはなぜですか? –

+1

これはまさにこれと同じ質問です:http://stackoverflow.com/questions/168931/unit-testing-the-app-config-file-with-nunit –

+0

OK、私はそれを閉じることができると思います。ポインタありがとう。 – FunLovinCoder

答えて

3

プロパティuseHostsFileとimportFileを使用してインターフェイスIConfigを実装することをお勧めします。次に、私はIConfigを実装するクラスConfigDefaultを除いて、このファイルへのすべての直接の依存関係を削除します。この実装では、通常の設定ファイルをロードします。各テストでは、IConfigから継承する別のクラスを実装することができます。 Dependecy Injectionを使用することをお勧めします。 Ninjectは無料で使いやすいです。

0

私はこのコードを使用します。ここでは

[TestMethod] 
    public void Test_general() 
    { 
     var cs = new ConnectionStringSettings(); 
     cs.Name = "ConnectionStrings.Oracle"; 
     cs.ConnectionString = "DATA SOURCE=xxx;PASSWORD=xxx;PERSIST SECURITY INFO=True;USER ID=xxx"; 
     cs.ProviderName = "Oracle.DataAccess.Client"; 

     var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); 
     //config.ConnectionStrings.ConnectionStrings.Clear(); 
     config.ConnectionStrings.ConnectionStrings.Remove(cs.Name); 
     config.ConnectionStrings.ConnectionStrings.Add(cs); 
     config.Save(ConfigurationSaveMode.Modified); 
     ConfigurationManager.RefreshSection("connectionStrings"); 

     // your code for your test here 
    } 
0

は、この課題への私の2セントです。単純に、新しいクラスAppSettingsを抽象レイヤーとして作成します。通常の操作では、アプリケーション設定ファイルから設定を読み込むだけです。しかし、単体テストは、スレッドごとの設定を上書きして、単体テストを異なる設定で並列実行することができます。ユニットテストで

function void MyApplicationMethod() { 
    string setting1 = AppSettings.Setting1; 
    string setting2 = AppSettings.Setting2; 
} 

、任意に選択されたオーバーライド設定:

[TestClass] 
public class MyUnitTest 
{ 
    [TestCleanup] 
    public void CleanupTest() 
    { 
     // 
     // Clear any app settings that were applied for the current test runner thread. 
     // 
     AppSettings.Instance = null; 
    } 

    [TestMethod] 
    public void MyUnitMethod() 
    { 
     AppSettings.Instance = new AppSettings(setting1: "New settings value for current thread"); 
     // Your test code goes here 
    } 
} 

注:アプリケーション・コードにおいて

internal sealed class AppSettings 
{ 
    private static readonly AppSettings instance; 
    private static ConcurrentDictionary<int, AppSettings> threadInstances; 
    private string _setting1; 
    private string _setting2; 

    static AppSettings() { instance = new AppSettings(); } 

    internal AppSettings(string setting1 = null, string setting2 = null) { 
     _setting1 = setting1 != null ? setting1 : Properties.Settings.Default.Setting1; 
     _setting2 = setting2 != null ? setting2 : Properties.Settings.Default.Setting2; 
    } 

    internal static AppSettings Instance { 
     get { 
      if (threadInstances != null) { 
       AppSettings threadInstance; 
       if (threadedInstances.TryGetValue(Thread.CurrentThread.ManagedThreadId, out threadInstance)) { 
        return threadInstance; 
       } 
      } 
      return instance; 
     } 

     set { 
      if (threadInstances == null) { 
       lock (instance) { 
        if (threadInstances == null) { 
         int numProcs = Environment.ProcessorCount; 
         int concurrencyLevel = numProcs * 2; 
         threadInstances = new ConcurrentDictionary<int, AppSettings>(concurrencyLevel, 5); 
        } 
       } 
      } 

      if (value != null) { 
       threadInstances.AddOrUpdate(Thread.CurrentThread.ManagedThreadId, value, (key, oldValue) => value); 
      } else { 
       AppSettings threadInstance; 
       threadInstances.TryRemove(Thread.CurrentThread.ManagedThreadId, out threadInstance); 
      } 
     } 
    } 

    internal static string Setting1 => Instance._setting1; 

    internal static string Setting2 => Instance._setting2; 
} 

、アクセス設定は、静的プロパティを使用してのAppSettingsのすべてのメソッドとしてクラスが内部として宣言されている場合は、属性を使用してユニットテストアセンブリに表示させる必要があります。 [assembly:InternalsVisibleTo( "<アセンブリ名>、PublicKey = <公開鍵> ")]

関連する問題