我正在尝试学习TDD,但我很难理解我需要编写的一个小应用程序测试的内容/方法.
应用程序的(简化的)规范如下:
它需要从用户那里获取csv文件的位置,word文档mailmerge模板的位置和输出位置.
然后,应用程序将读取csv文件,对于每一行,将数据与单词模板合并并输出到指定的文件夹.
为了清楚起见,我不会问我将如何编写这样的应用程序,因为我确信如果我继续开始,我知道该怎么做.但是,如果我想使用TDD进行操作,那么我会猜测我不想测试读取真正的csv文件,或者测试执行合并的第三方组件或转换为pdf.
我认为只是一些一般的TDD指导将是一个很大的帮助!
Jef*_*nal 34
我首先考虑程序的每个步骤的场景,从失败案例及其预期行为开始:
用户提供null csv文件位置(抛出一个ArgumentNullException
).
用户提供一个空的csv文件位置(抛出一个ArgumentException
).
用户指定的csv文件不存在(您认为合适的任何内容).
接下来,为每个场景编写测试并确保它失败.接下来,编写足够的代码以使测试通过.对于某些条件来说这很容易,因为使测试通过的代码通常是最终代码:
public class Merger {
public void Merge(string csvPath, string templatePath, string outputPath) {
if (csvPath == null) { throw new ArgumentNullException("csvPath"); }
}
}
Run Code Online (Sandbox Code Playgroud)
之后,进入标准方案:
指定的csv文件有一行(合并应调用一次,输出写入预期位置).
指定的csv文件有两行(merge应调用两次,输出写入预期位置).
输出文件的名称符合您的期望(无论是什么).
等等.一旦你进入第二阶段,你将开始识别你想要存根和模拟的行为.例如,检查文件是否存在 - .NET不容易将其存根,因此您可能需要创建一个适配器接口和类,以便将程序与实际文件系统隔离(至更不用说实际的CSV文件和邮件合并模板了.还有其他技术可用,但这种方法相当标准:
public interface IFileFinder { bool FileExists(string path); }
// Concrete implementation to use in production
public class FileFinder: IFileFinder {
public bool FileExists(string path) { return File.Exists(path); }
}
public class Merger {
IFileFinder finder;
public Merger(IFileFinder finder) { this.finder = finder; }
}
Run Code Online (Sandbox Code Playgroud)
在测试中,您将传入存根实现:
[Test]
[ExpectedException(typeof(FileNotFoundException))]
public void Fails_When_Csv_File_Does_Not_Exist() {
IFileFinder finder = mockery.NewMock<IFileFinder>();
Merger merger = new Merger(finder);
Stub.On(finder).Method("FileExists").Will(Return.Value(false));
merger.Merge("csvPath", "templatePath", "outputPath");
}
Run Code Online (Sandbox Code Playgroud)