用属性get或set注入伪对象
在使用属性注入时,要为每个要注入的依赖添加一个属性get和set,然后在被测试的代码中需要的地方使用这些依赖。 使用属性注入依赖,比使用构造函数简单,因为每个测试可以只设置自己需要的属性。 但是在使用属性前,应该先构造一个被注入依赖的实例,以便在不注入属性时使用。下面程序中有相应说明。
下面是伪代码
//属性注入,伪代码
public IExtensionManager Manager
{
get { return m_manager; }
set { m_manager = value; }
}
IExtensionManager m_manager
IsValidFileName(string)
{
if (m_manager.IsValid(file))
...
}
实现代码如下:
class LogAnalyzerPropertyInject
{
private IExtensionManager manager;
public LogAnalyzerPropertyInject()
{
//调用类的时候构造,如果不使用下面的属性,则这个起作用。
//这样就做到了使用属性是可选的,在不用属性的情况下正常使用。
manager = new FileExtensionManager();
}
public IExtensionManager ExtensionManager
{
//在使用属性时,就可以把上面构造的FileExtensionManager() 覆盖掉了。
get { return manager; }
set { manager = value; }
}
public bool IsValidLogFileName(string fileName)
{
return manager.IsValid(fileName);
}
//下面两个是定义的实现类和对应抽象出来的接口
public interface IExtensionManager
{
bool IsValid(string fileName);
}
public class FileExtensionManager : IExtensionManager
{
public bool IsValid(string fileName)
{
//读取文件
if (string.IsNullOrEmpty(fileName))
{
throw new ArgumentException("filename has to be provided");
}
if (!fileName.EndsWith(".SLF", StringComparison.CurrentCultureIgnoreCase))
{
return false;
}
return true;
}
}
}
测试代码如下:
[TestFixture]
public class LogAnalyzerPropertyInjectTests
{
[Test]
public void IsValidFileName_SupportExtension_ReturnTrue()
{
//使用前面构造函数注入用的桩
FakeExtensionManager myFakeManager = new FakeExtensionManager();
myFakeManager.WillBeValid = true;
LogAnalyzerPropertyInject log = new LogAnalyzerPropertyInject();
log.ExtensionManager = myFakeManager;
bool result = log.IsValidLogFileName("anything.anyextension");
Assert.True(result);
}
}
使用属性注入的时机
如果想表明被测试类的某个依赖项是可选的,或者测试可以放心使用默认创建的这个依赖项实例,就可以使用属性注入。