Visual Studio Team Editionのテストフレームワークでいくつかの自動テストを準備しました。プログラムで行われる通常の方法に従って、テストの1つがデータベースに接続するようにします。
string r_providerName = ConfigurationManager.ConnectionStrings["main_db"].ProviderName;
しかし、私はこの行で例外を受け取っています。これは、ConfigurationManagerがシングルトンであるために発生していると思われます。単体テストでシングルトンの問題をどのように回避できますか?
返信いただきありがとうございます。それらはすべて非常に有益でした。
コンストラクター依存性注入を使用できます。例:
public class SingletonDependedClass
{
private string _ProviderName;
public SingletonDependedClass()
: this(ConfigurationManager.ConnectionStrings["main_db"].ProviderName)
{
}
public SingletonDependedClass(string providerName)
{
_ProviderName = providerName;
}
}
これにより、テスト中に接続文字列をオブジェクトに直接渡すことができます。
また、Visual Studio Team Editionテストフレームワークを使用する場合は、パラメーターをプライベートにしてコンストラクターを作成し、アクセサーを介してクラスをテストできます。
実際、私はそのような問題をあざけることで解決します。例:
シングルトンに依存するクラスがあります:
public class Singleton
{
public virtual string SomeProperty { get; set; }
private static Singleton _Instance;
public static Singleton Insatnce
{
get
{
if (_Instance == null)
{
_Instance = new Singleton();
}
return _Instance;
}
}
protected Singleton()
{
}
}
public class SingletonDependedClass
{
public void SomeMethod()
{
...
string str = Singleton.Insatnce.SomeProperty;
...
}
}
まず、SingletonDependedClass
インスタンスをリファクタリングして、Singleton
インスタンスをコンストラクターパラメーターとして取得する必要があります。
public class SingletonDependedClass
{
private Singleton _SingletonInstance;
public SingletonDependedClass()
: this(Singleton.Insatnce)
{
}
private SingletonDependedClass(Singleton singletonInstance)
{
_SingletonInstance = singletonInstance;
}
public void SomeMethod()
{
string str = _SingletonInstance.SomeProperty;
}
}
SingletonDependedClass
のテスト( Moqモッキングライブラリ が使用されます):
[TestMethod()]
public void SomeMethodTest()
{
var singletonMock = new Mock<Singleton>();
singletonMock.Setup(s => s.SomeProperty).Returns("some test data");
var target = new SingletonDependedClass_Accessor(singletonMock.Object);
...
}
ブックからの例: レガシーコードを効果的に使用する
ここにも同じ答えがあります: https://stackoverflow.com/a/28613595/929902
テストハーネスでシングルトンを含むコードを実行するには、シングルトンプロパティを緩和する必要があります。方法は次のとおりです。最初のステップは、シングルトンクラスに新しい静的メソッドを追加することです。このメソッドにより、シングルトンの静的インスタンスを置き換えることができます。これをsetTestingInstanceと呼びます。
public class PermitRepository
{
private static PermitRepository instance = null;
private PermitRepository() {}
public static void setTestingInstance(PermitRepository newInstance)
{
instance = newInstance;
}
public static PermitRepository getInstance()
{
if (instance == null) {
instance = new PermitRepository();
}
return instance;
}
public Permit findAssociatedPermit(PermitNotice notice) {
...
}
...
}
セッターが用意できたので、PermitRepositoryのテストインスタンスを作成して設定できます。テストのセットアップで次のようなコードを書きたいと思います。
public void setUp() {
PermitRepository repository = PermitRepository.getInstance();
...
// add permits to the repository here
...
PermitRepository.setTestingInstance(repository);
}
ここで、より一般的な問題に直面しています。誤用すると、シングルトンはテスト可能性を妨げます。
私は 詳細な分析 分離設計のコンテキストでこの問題を実行しました。私のポイントを要約してみます: