使用工厂方法注入伪对象
在使用工厂注入是在对一个对象操作前才能得到其实例,而不是通过构造函数或者属性得到。这种情况的不同之处在于发起桩请求的对象是被测试代码。 这种方式是在工厂类中放置一个接缝,在调用前注入伪对象,覆盖默认对象。
以下是伪代码:
//被测试类
ClassUnderTest{
ClassUnderTest(I){
m_manager=FactoryClass.Create();
}
IExtensionManager m_manager
IsValidFileName(string){
if(m_manager.Isvalid(file))
...
}
}
//工厂类
FactoryClass{
Static IExtensionManager Create(){
return manager;
}
IExtensionManager manager
Static SetManager(IExtensionManager mgr){
manager=mgr;
...
}
}
实现代码
public class LogAnalyzerFactoryInject
{
private IExtensionManager manager;
public LogAnalyzerFactoryInject()
{
manager = ExtensionManagerFactory.Create();
}
public bool IsValidLogFileName(string fileName)
{
return manager.IsValid(fileName)
&& Path.GetFileNameWithoutExtension(fileName).Length > 5;
}
}
class ExtensionManagerFactory
{
private static IExtensionManager customManager = null;
public static IExtensionManager Create()
{
if (customManager != null)
return customManager;
return new FileExtensionManager();
}
public void SetManager(IExtensionManager mgr)
{
customManager = mgr;
}
}
测试代码
public class LogAnalyzerFactoryInjectTests
{
public void IsValidFileName_SupportedExtension_ReturnTrue()
{
//设置要使用的桩,并给其赋值使其返回True
FakeExtensionManager myFakeManager = new FakeExtensionManager();
myFakeManager.WillBeValid = true;
ExtensionManagerFactory factory = new ExtensionManagerFactory();
factory.SetManager(myFakeManager);
LogAnalyzerFactoryInject log = new LogAnalyzerFactoryInject();
bool result = log.IsValidLogFileName("anything.anyextension");
Assert.True(result);
}
}
工厂类中增加接缝的好处
可以设置一个全局#debug开关,在开关打开时,可以让接缝制动发送一个伪对象或者可测试对象,而不是默认实现。这样不太容易,但是到了测试系统时,会非常有用。
发布版中隐藏接缝
如果不想接缝在发布版中可见,可以用一条编译参数控制接缝语句(增加构造函数、属性设置方法或者工厂属性设置方法)的编译。