假 static/singleton class/method 使用微软假货

Fake static/singleton class/method using microsoft fakes

我有 class,它具有私有构造函数并通过 public 静态方法(单例 class)访问。无法创建此 class 中的单例对象。

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

我的测试class:

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

这种情况下如何调用fake方法?无法使用此代码创建假的实例。

我建议将 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);
    }

但是如果您仍然想在不更改代码的情况下模拟静态调用,则应该像本示例中那样使用 Shims http://www.richonsoftware.com/post/2012/04/05/using-stubs-and-shim-to-test-with-microsoft-fakes-in-visual-studio-11.aspx