简体   繁体   中英

Fake static/singleton class/method using microsoft fakes

I have class which has private constructor and accessed through public static method ( singleton class). Not able to create singleton object of this class in fakes.

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

I want to Test Following method:

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

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

How to call fake method in this case? Unable to create instance of fake with this code.

I suggest to move creation of dvqBusinessManager outside of the method.

This way

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

Or

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

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

So you can inject a fake object to the method and test it, without calling GetInstance method.

Or you can implement and use a factory pattern and hide the static call there.

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

But if you still want to mock a static call without changing the code, you should use Shims like in this example http://www.richonsoftware.com/post/2012/04/05/using-stubs-and-shim-to-test-with-microsoft-fakes-in-visual-studio-11.aspx .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM