2

我有一個具有私有構造函數並通過公共靜態方法(單例類)訪問的類。無法在假貨中創建此類的單例對象。假靜態/單類/使用微軟假貨的方法

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; 
     } 
} 

我想測試一下下面的方法:

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

我的測試類:

[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 
     } 
    } 
} 

如何調用在這種情況下,假的方法?無法使用此代碼創建假實例。

+3

您剛剛瞭解到單身人士是「反模式」的原因之一 – 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

相關問題