我想创建单元测试代码,模拟调用.Net System.IO类,所以我可以真正进行单元测试而不是依赖于文件系统。 我正在使用SystemWrapper类来环绕BCL类。如何使用.Net IO类创建可测试的代码?
我想获得一个简单的例子,看看是否存在一个文件。
我遇到的问题是,在类注射的依赖不起作用,因为实例的依赖(通过StructureMap)需要知道通过什么构造函数的参数,这将不提供在那个时候,也有没有默认的构造函数。
示例代码:
// don't want to create dependency here like so
//IFileInfoWrap fileInfoWrap = new FileInfoWrap(filename);
// using service locator (anti-pattern?!) since it can't be
// injected in this class
var fileInfoWrap = ObjectFactory.GetInstance<IFileInfoWrap>(
new ExplicitArguments(new Dictionary<string, object>
{
{"fileName", filename}
}));
Console.WriteLine("File exists? {0}", fileInfoWrap.Exists);
我不喜欢的是依赖没有注入,ObjectFactory的不应该在这里(但我认为创建这个没有别的办法)。 ExplicitArguments使其变得混乱,参数名称是一个魔术字符串。
,我得到这个工作StructureMap配置类需要知道我想用(我刚开始用StructureMap所以这可能不是设置它以正确的方式)显式哪个构造:
ObjectFactory.Initialize(x =>
{
x.Scan(scan =>
{
scan.AssembliesFromPath(".");
scan.RegisterConcreteTypesAgainstTheFirstInterface();
scan.WithDefaultConventions();
});
// use the correct constructor (string instead of FileInfo)
x.SelectConstructor(() => new FileInfoWrap(null as string));
// setting the value of the constructor
x.For<IFileInfoWrap>()
.Use<FileInfoWrap>()
.Ctor<string>("fileName")
.Is(@".");
});
有没有人找到更好的解决方案来创建System.IO类的可测试代码? 我知道问题的一部分是在System.IO类的设计中。
SystemWrapper主要含有极其漏抽象。对Streams,TextWriter,TextReader等进行IO建模将变得简单和容易。这些类已经是抽象的,完全消除了对SystemWrapper的需求。 – 2012-01-07 10:38:52
另一个投票流 – 2012-01-07 11:36:27
我的发现与SystemWrapper是它似乎是一个很好的接口包装,但它仍然是一个死胡同,因为原始类的工作方式。 例如,返回一个FileInfo对象数组不能被正确模拟。滚动我自己更简化的包装,它不需要模仿现有的类,而更多的工作会导致一个可行的解决方案恕我直言。 – 2012-01-08 06:48:37