Reputation: 769
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.
Upvotes: 4
Views: 5567
Reputation: 5488
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.
Upvotes: 1