使用微软假货的假静态/单件类/方法

时间:2016-04-20 09:56:07

标签: c# unit-testing microsoft-fakes vs-unit-testing-framework

我有一个具有私有构造函数的类,并通过公共静态方法(singleton类)访问。无法在假货中创建此类的单个对象。

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

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

1 个答案:

答案 0 :(得分: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中的Shims。