我有这个方法签名:List<ITMData> Parse(string[] lines)
ITMData
有 35 个属性。
您将如何有效地测试这样的解析器?
问题:
- 我应该加载整个文件吗(我可以使用 System.IO)吗?
- 我应该将文件中的一行放入字符串常量吗?
- 我应该测试一行还是多行
- 我应该测试 ITMData 的每个属性还是应该测试整个对象?
- 如何命名我的测试?
编辑
我将方法签名更改为 ITMData Parse(string line)
.
测试代码:
[Subject(typeof(ITMFileParser))]
public class When_parsing_from_index_59_to_79
{
private const string Line = ".........";
private static ITMFileParser _parser;
private static ITMData _data;
private Establish context = () => { _parser = new ITMFileParser(); };
private Because of = () => { _data = _parser.Parse(Line); };
private It should_get_fldName = () => _data.FldName.ShouldBeEqualIgnoringCase("HUMMELDUMM");
}
编辑 2
我仍然不确定是否应该只测试每个类的一个属性。在我看来,这允许我为规范提供更多信息,即当我解析从索引 59 到索引 79 的一行时,我得到 fldName。如果我测试一个类中的所有属性,我将丢失此信息。我是否过度指定了我的测试?
我的测试现在看起来像这样:
[Subject(typeof(ITMFileParser))]
public class When_parsing_single_line_from_ITM_file
{
const string Line = ""
static ITMFileParser _parser;
static ITMData _data;
Establish context = () => { _parser = new ITMFileParser(); };
private Because of = () => { _data = _parser.Parse(Line); };
It should_get_fld??? = () => _data.Fld???.ShouldEqual(???);
It should_get_fld??? = () => _data.Fld???.ShouldEqual(???);
It should_get_fld??? = () => _data.Fld???.ShouldEqual(???);
It should_get_fld??? = () => _data.Fld???.ShouldEqual(???);
It should_get_fld??? = () => _data.Fld???.ShouldEqual(???);
It should_get_fld??? = () => _data.Fld???.ShouldEqual(???);
It should_get_fld??? = () => _data.Fld???.ShouldEqual(???);
...
}
最佳答案
Should I load the whole file (May I use System.IO)?
如果您这样做,它就不再是单元测试——它变成了集成或回归测试。如果您希望它显示单元测试不会显示的可能错误,则可以这样做。但这不太可能。
你可能最好进行单元测试,至少在开始时是这样。
Should I put a line from the file into a string constant?
如果您打算编写多个使用同一输入行的测试,那么当然可以。但就个人而言,我可能倾向于编写一堆不同的测试,每个测试都传递不同的输入字符串。在这一点上,没有太多理由创建一个常量(除非它是一个局部常量,在测试方法内部声明)。
Should I test one or more lines?
您没有指定,但我假设您的输出与您的输入是一对一的——也就是说,如果您传入三个字符串,您将获得三个 ITMData
s 返回。在这种情况下,对多线测试的需求将受到限制。
几乎总是值得测试退化的情况,在这种情况下将是一个空字符串数组(零行)。至少有一个不止一行的测试可能是值得的,这样你就可以确保你的迭代中没有愚蠢的错误。
但是,如果您的输出与您的输入是一对一的,那么您确实有另一种方法想要退出——您应该有一个 ParseSingleLine
方法。那么您的 Parse
将只不过是迭代行和调用 ParseSingleLine
。您仍然需要对 Parse 进行一些测试,但您的大部分测试将集中在 ParseSingleLine
上。
关于c# - 如何使用 MSpec 有效地测试固定长度的平面文件解析器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7078652/