我的问题是你真的需要访问文件 IO 并通过单元测试进行过滤和转换吗?这不是集成测试吗?
准确地说 - 在这种情况下,您正在测试 3 件事 - 文件 IO 系统、实际文件内容和Convert
方法本身。
我认为您需要考虑重组代码以使其更适合单元测试(这不是对您的代码的批评!)。考虑您对Convert
方法的定义:
在其中我指定输入文件路径和过滤器字符串
所以你的Convert
方法实际上是在做两件事——打开/读取文件,以及转换内容。您需要改变一些事情,以便 Convert 方法只做一件事 - 具体来说,执行字符串(或实际上是流)的转换,而无需提及它的来源。
这样,您可以Convert
通过为方法提供您在单元测试中定义的字符串来正确测试该方法- 一个测试使用已知的好数据,一个测试使用已知的坏数据。
例如
void Convert_WithGoodInput_ReturnsTrue()
{
var input="this is a piece of data I know is good and should pass";
var sut = new Converter(); //or whatever it's called :)
bool actual = sut.Convert(input);
Assert.AreEqual(true,actual,"Convert failed to convert good data...");
}
void Convert_WithBadInput_ReturnsFalse()
{
var input="this is a piece of data I know is BAD and should Fail. Bad Data! Bad!";
var sut = new Converter(); //or whatever it's called :)
bool actual = sut.Convert(input);
Assert.AreEqual(false,actual,"Convert failed to complain about bad data...");
}
当然,在您的Convert
方法中,您正在做各种神秘而奇妙的事情,此时您可能会查看该方法,看看是否可以将其拆分为多个内部方法,其功能可能由单独的类提供,您将其作为Converter
类的依赖项提供,而这些又可以单独进行测试。
通过这样做,您将能够测试转换器方法的功能,并且您将能够开始使用 Mocks,以便您也可以测试它的功能行为- 例如确保frobber
仅调用一次, 并且总是在gibber
,之前gibber
总是调用munger
, 等等。
奖金
但是等等,还有更多!!!!1!- 一旦你的转换器类/方法被安排成这样,你会突然发现你现在可以实现一个 XML 到制表符分隔,或 XML 到 JSON,或 XML 到???? 只需编写相关组件并将其插入 Converter 类即可。松耦合FTW!
例如(在这里我只是在想象你的转换函数的胆量可能如何工作)
public class Converter
{
public Converter(ISourceReader reader, IValidator validator, IFilter filter,IOutputformatter formatter)
{
//boring saving of dependencies to local privates here...
}
public bool Convert(string data,string filter)
{
if (!validator.Validate(data)) return false;
var filtered = filter.Filter(data);
var raw = reader.Tokenise(filtered);
var result = formatter.Format(raw);
//and so on
return true; //or whatever...
}
}
当然,我并不是要告诉你如何编写代码,但上面是一个非常可测试的单元和功能测试类,因为你可以在你喜欢的地方混合和匹配 Mocks、Stubs 和 Reals。