Xml的解析和错误消息的显示是单独的问题,所以解析器不应该有关于如何显示错误消息的任何知识。
根据您的需求,有几个选项:
例外
我经常被生活准则:“如果一个方法不能做的工作,抛出一个异常”。如果您需要停止第一个错误,那么例外就是要走的路。
从单元测试的角度来看,如果您传递非法数据,请验证代码使用[ExpectedException]属性抛出异常。
[TestMethod, ExpectedException(typeof(ParserValidationException))]
public void IllegalDataShouldThrowValidationErrors()
{
var parser = new MyParser();
parser.Parse(dataThatContainsErrors);
}
但是,如果您需要忽略非法数据并报告错误,则可能需要采用其他方法。
专门返回类型
如果您需要收集所有的错误,这是最好的,目的在于保持解析结果和错误一起。
public class ParsedResult<T>
{
public T Result;
public List<string> Warnings;
}
从单元测试的角度来看,如果您传递非法数据,您应该验证警告列表不是空的。
[TestMethod]
public void ParsedResultsForIllegalDataShouldContainWarnings()
{
var parsedResult = new MyParser.Parse<Foo>(dataThatContainsErrors);
Assert.IsNotNull(parsedResult);
Assert.IsNotNull(parsedResult.Result);
Assert.AreEqual(1, parsedResult.Warnings.Count);
}
错误记者
传递一个合作者到对象并将其举报的调查结果。
public ObjectToReturn Parse(string xml, IProgressReporter progress)
{
// create xml reader
// read values from xml
// if a value is invalid, log it
progress.AddMessage("property x was invalid. ")
}
进度报告可以在你的MessageBox的包装,或者它可能是一个控制台输出,记录仪等。从单元测试的角度来看,你可以创建一个测试双捕获的消息,或者你可以使用模拟框架并验证它被称为一定的次数。这是一个使用Moq的例子。
var mockReporter = new Mock<IProgressReporter>();
IProgressReporter reporter = mockReporter.Object;
var parser = new MyParser();
var illegalData = // your illegal data;
var result = parser.Parse(illegalData, parser);
Assert.IsNotNull(result, "The value was not parsed correctly.");
mockReporter.Verify(r => r.AddMessage(It.IsAny<string>()), Times.AtLeast(1));