伪造方法--使用一个局部的工厂方法(抽取和重写)
使用被测试类中一个局部的虚方法作为工厂方法,获取扩展名管理器实例。 因为这个方法是虚方法,它可以在派生类中被重写,这就制造了你需要的接缝。 通过集成被测试类得到一个新类,在新类中配置需要返回的实例,重写这个虚工厂方法,返回配置好的实例,你就在类中注入了一个桩。 之后对这个新的派生类进行测试。
步骤@H_301_13@
- 在被测试类中:
- 在测试项目中:
- 在测试代码中:
- 创建一个桩类的实例,此桩类实现了所要求的接口(IExtensionManager);
- 创建新派生类而非被测试类的实例;
- 配置这个新实例的公共字段(之前创建的字段),设置成你在测试中创建的桩实例。
@H_502_47@
以下是伪代码
Virtual IExtensionManager getExtensionManager()
{
return
new FileExtensionManager() ///manager
}
IsValidFileName(string)
{
IExtensionManager manager = getExtensionManager();
if(manager.isvalid(file)) ///manager
...
}

//测试代码
public IExtensionManager manager;
override IExtensionManager getExtensionManager()
{
return
manager ///manager!!这里的Manager把new FileExtensionManager()替换掉了
}
IsValidFileName(string)
{
IExtensionManager manager = getExtensionManager();
if(manager.isvalid(file)) ///manager
...
}
实现代码
public class LogAnalyzerVirtualFactory
{
//这个工厂方法,被定义为虚函数,以便后面重写并注入伪对象
protected virtual IExtensionManager GetManager()
{
return new FileExtensionManager();
}
public bool IsValidLogFileName(string fileName)
{
return GetManager().IsValid(fileName);
}
}
测试代码
[TestFixture]
public class LogAnalyzerVirtualFactoryTest
{
[Test]
public void OverrideTest()
{
//设置要使用的桩,并赋值
FakeExtensionManager stub = new FakeExtensionManager();
stub.WillBeValid = true;
//创建被测试类的派生类实例
LogAnalyzerVirtualFactoryOverride logan = new LogAnalyzerVirtualFactoryOverride(stub);
bool result = logan.IsValidLogFileName("file.ext");
Assert.True(result);
}
}
- 创建一个桩类的实例,此桩类实现了所要求的接口(IExtensionManager);
- 创建新派生类而非被测试类的实例;
- 配置这个新实例的公共字段(之前创建的字段),设置成你在测试中创建的桩实例。
以下是伪代码
这种技术称为抽取和重写(extract and override) 这种技术的好处是,不需要进入更深层次(改变调用栈深处的依赖)即可直接替换依赖项,实现起来快速干净。这样就可以编写更少的接口,更多的虚函数。