伪造方法--使用一个局部的工厂方法(抽取和重写)
使用被测试类中一个局部的虚方法作为工厂方法,获取扩展名管理器实例。 因为这个方法是虚方法,它可以在派生类中被重写,这就制造了你需要的接缝。 通过集成被测试类得到一个新类,在新类中配置需要返回的实例,重写这个虚工厂方法,返回配置好的实例,你就在类中注入了一个桩。 之后对这个新的派生类进行测试。
步骤
- 在被测试类中:
- 在测试项目中:
- 在测试代码中:
- 创建一个桩类的实例,此桩类实现了所要求的接口(IExtensionManager);
- 创建新派生类而非被测试类的实例;
- 配置这个新实例的公共字段(之前创建的字段),设置成你在测试中创建的桩实例。
以下是伪代码
Virtual IExtensionManager getExtensionManager() { return new FileExtensionManager() ///manager } IsValidFileName(string) { IExtensionManager manager = getExtensionManager(); if(manager.isvalid(file)) ///manager ... } ![伪造方法](https://static.oschina.net/uploads/img/201705/24231701_DEDF.png "伪造方法") //测试代码 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); } }
这种技术称为抽取和重写(extract and override) 这种技术的好处是,不需要进入更深层次(改变调用栈深处的依赖)即可直接替换依赖项,实现起来快速干净。这样就可以编写更少的接口,更多的虚函数。