我会首先考虑程序每个步骤的场景,从失败案例及其预期行为开始:
用户提供了一个空的 csv 文件位置(抛出一个ArgumentNullException)。
用户提供一个空的 csv 文件位置(抛出一个ArgumentException)。
用户指定的 csv 文件不存在(随便你认为合适的)。
接下来,为每个场景编写一个测试并确保它失败。接下来,编写足够的代码以使测试通过。对于其中一些情况,这很容易,因为使您的测试通过的代码通常是最终代码:
public class Merger {
public void Merge(string csvPath, string templatePath, string outputPath) {
if (csvPath == null) { throw new ArgumentNullException("csvPath"); }
}
}
之后,进入标准场景:
等等。一旦进入第二阶段,您将开始识别要存根和模拟的行为。例如,检查文件是否存在 - .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; }
}
在测试中,您将传入一个存根实现:
[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");
}