失败try/catch块读取csv
问题描述:
我正在测试解析CSV的C#应用程序的单元测试。我在94%的代码覆盖率,因为我不能强迫它失败try/catch块......我使用CsvHelper从的NuGet http://joshclose.github.io/CsvHelper失败try/catch块读取csv
public void ParseCsv([FromBody] string csvText)
{
var parseCsv = new XsvData(new[] { "\t", "," });
try
{
using (var reader = new XsvReader(new StringReader(csvText)))
{
parseCsv.Read(reader, headerExists: true);
}
}
catch (Exception)
{
var response = new HttpResponseMessage(HttpStatusCode.BadRequest)
{
Content = new StringContent("Unable to read CSV."),
ReasonPhrase = "Invalid CSV"
};
throw new HttpResponseException(response);
}
}
我试过路过的最不起眼的琴弦我能想到的它,但它使通过这个,后来就在函数出错了..
[TestMethod]
//[ExpectedException(typeof(HttpResponseException))]
public void TestUploadCsv_UploadingCsvNonCsv()
{
const string csvText = "[email protected] [email protected] fjkqeqir%[email protected] ujewqh$phfuw \n hfwu- ihfq&if*[email protected] afuhwu- [email protected]";
var context = GetMyFakeEntityDatabase();
var controller = new MyController(context);
controller.ParseCsv(csvText);
}
的try/catch块后,我有一个强制的所有头存在的部分,它在那里失败了,但是在这个例子中,它在阅读过程中应该失败。我如何强制我的单元测试失败?任何帮助表示赞赏!提前致谢。
答
我解决了这个问题,只是将它传递给null,就像评论中推荐的juharr一样。
答
使用提供者模式和接口,而不是具体类型,然后运行你的单元测试,通过代替抛出异常的模拟对象。
详细:
- 提取接口
IXsvReader
从XsvReader
- 实施的
IXsvReader
一个新的具体实例上Read
抛出异常。为每个你希望单独处理的错误创建一个具体的实现类(在这种情况下,你只需要一个)。 - 在包含
ParseCSV
方法的类中,具有可设置的IXsvProvider
的属性。在该类的构造函数中,将该属性设置为将返回“真实”读者的默认提供者。这个接口只有一个方法,GetXsvReader(string text)
- 在你的测试类中,用ParseCSV函数新建类,然后注入一个IXsvProvider,它返回你的“dummy”
IXsvReader
,只要你试图使用方法。
答
您应该使用Inversion of Control
并将依赖关系注入到控制器中,而不是在控制器操作中创建它。这样你就可以嘲笑读者,并且让它抛出一个,除此之外。
我打算根据CsvHelper
编写此示例,因为这就是您所说的使用,即使示例看起来不像它。
大致为:
public class MyController : Controller
{
private readonly ICsvReader csv;
public MyController(ICsvReader csv)
{
this.csv = csv;
}
}
public class CsvReaderMock : ICsvReader
{
public void Read()
{
throw new Exception();
}
}
现在你可以使用你的模拟ICsvReader
测试时,它会抛出异常。
此外,你应该只测试一种方法。如果你的方法具有依赖性,你应该传递它们而不是创建它们,所以你只能测试该方法中的代码,而不能测试它创建的类。
+1用于测试代码如何处理失败。 – 2014-10-01 15:59:55
您可以将'null'传递给'csvText'。 – juharr 2014-10-01 16:01:14
@juharr它目前的写法,可以工作,但它不是一个非常通用的解决方案。如果他想要空/空字符串与无效语法的不同状态代码会怎样。 – 2014-10-01 16:08:45