假 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。
我有 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。