2

プライベートコンストラクタを持ち、public staticメソッド(シングルトンクラス)を介してアクセスするクラスがあります。偽物でこのクラスのシングルトンオブジェクトを作成することはできません。偽のstatic/singletonクラス/メソッドを使ったMicrosoftの偽物

public class MyBusinessManager : BusinessManager 
{ 
private MyBusinessManager objMyBusinessManager; 

private MyBusinessManager (MyBusinessManager dvqsDataManager) 
     { 
      objMyBusinessManager= dvqsDataManager; 
     } 
public static MyBusinessManager GetInstance() // out 
     { 
      MyBusinessManager dvqsDataMgr = new MyBusinessManager(); 

      return new MyBusinessManager (dvqsDataMgr); 
     } 

public bool MyBusinessManagerMethod (int bm) 
     { 
       if(bm == 0) 
       return true; 

       return false; 
     } 
} 

私は次のような方法をテストしたい:この場合には偽のメソッドを呼び出す方法を

[TestClass] 
public class MyService_UT 
{ 
    [TestMethod] 
    public void TestMethod1() 
    { 
     using (ShimsContext.Create()) 
     { 
     ShimMyBusinessManager.GetInstance =() => { return new ShimMyBusinessManager(); }; 
     ShimMyBusinessManager.AllInstances.MyServiceMethodInt32 = (a) =>{ 
           return true; 
           } 
     MyService obj = new MyService(); 
     Assert.IsTrue(obj.MyServiceMethod(1))// doesn't call fake method 
     } 
    } 
} 

public class MyService 
{ 
    public bool MyServiceMethod(int serviceParam) 
    { 
     MyBusinessManager dvqBusinessManager = MyBusinessManager.GetInstance(); // make fake call 
     return dvqBusinessManager.MyBusinessManagerMethod(serviceParam); // make fake service call 
    } 
} 

私のテストクラスを?このコードで偽のインスタンスを作成できません。

+3

シングルトンが「アンチパターン」である理由の1つを学んだだけです。 – Joe

+0

正しい。これは古いコードです。しかし、どのようにこれを抜け出すために? – user2323308

+1

テストするために厄介なコードの別の層を上に置くのではなく、むしろ厄介な古いコードをリファクタリングする方が簡単かもしれません。 – nvoigt

答えて

1

dvqBusinessManagerの作成をメソッド外に移動することをお勧めします。

この方法

MyBusinessManager dvqBusinessManager = MyBusinessManager.GetInstance(); 
    public bool MyServiceMethod(int serviceParam) 
    { 
     return dvqBusinessManager.MyBusinessManagerMethod(serviceParam); // make fake service call 
    } 

それとも

public bool MyServiceMethod(int serviceParam) 
    { 
     MyBusinessManager dvqBusinessManager = MyBusinessManager.GetInstance(); 
     MyServiceTestableMethod(dvqBusinessManager, serviceParam); 
    } 

    public bool MyServiceTestableMethod(MyBusinessManager manager, int serviceParam) 
    { 
     return manager.MyBusinessManagerMethod(serviceParam); 
    } 

だから、メソッドに偽のオブジェクトを注入し、GetInstanceメソッドを呼び出すことなく、それをテストすることができます。

または、ファクトリパターンを実装して使用し、そこで静的呼び出しを非表示にすることができます。

public interface IServiceFactory 
    { 
     MyBusinessManager GetInstance(); 
    } 

    public class ServiceFactory : IServiceFactory 
    { 
     public MyBusinessManager GetInstance() 
     { 
      return MyBusinessManager.GetInstance(); 
     } 
    } 

    IServiceFactory factory = new ServiceFactory(); 
    public bool MyServiceMethod(int serviceParam) 
    { 
     MyBusinessManager dvqBusinessManager = factory.GetInstance(); 
     dvqBusinessManager.MyBusinessManagerMethod(serviceParam); 
    } 

しかし、あなたはまだ、コードを変更せずに、静的呼び出しをモックとしたい場合は、この例http://www.richonsoftware.com/post/2012/04/05/using-stubs-and-shim-to-test-with-microsoft-fakes-in-visual-studio-11.aspxのようにシムを使用する必要があります。

+0

ありがとうございます。私はこの問題を解決するためにリンクに記載されているコードを使用しました。 – user2323308