C# 尝试/捕获块读取csv失败

C# 尝试/捕获块读取csv失败,c#,unit-testing,csv,try-catch,csvhelper,C#,Unit Testing,Csv,Try Catch,Csvhelper,我正在对解析CSV的C#应用程序进行单元测试。我有94%的代码覆盖率,因为我不能强迫它通过try/catch块。。。我用的是Nuget的CsvHelper 我尝试过将我能想到的最模糊的字符串传递给它,但它成功地完成了这一过程,并且在函数中出现了错误 [TestMethod] //[ExpectedException(typeof(HttpResponseException))] public void TestUploadCsv_UploadingCsvNonCsv() { const

我正在对解析CSV的C#应用程序进行单元测试。我有94%的代码覆盖率,因为我不能强迫它通过try/catch块。。。我用的是Nuget的CsvHelper

我尝试过将我能想到的最模糊的字符串传递给它,但它成功地完成了这一过程,并且在函数中出现了错误

[TestMethod]
//[ExpectedException(typeof(HttpResponseException))]
public void TestUploadCsv_UploadingCsvNonCsv()
{
    const string csvText = "fhfhk@- jhjfh@ajh- fjkqeqir%hjewq@hf- ujewqh$phfuw \n hfwu- ihfq&if*u@q- afuhwu- fhiue@wfhiuewhiuf";
    var context = GetMyFakeEntityDatabase();
    var controller = new MyController(context);
    controller.ParseCsv(csvText);
}

在try/catch块之后,我有一个强制执行所有存在的头的部分,它在那里失败了,但在读取过程中应该失败,例如本例。我如何强制我的单元测试失败?感谢您的帮助!提前感谢。

使用提供程序模式和接口而不是具体类型,然后通过替换将引发异常的模拟对象来运行单元测试

详细内容:

  • XsvReader
  • 实现一个新的
    IXsvReader
    具体实例,该实例在
    Read
    上抛出异常。为您希望单独处理的每个错误创建一个具体的实现类(在本例中,您只需要一个)
  • 在包含
    ParseCSV
    方法的类中,具有可设置的
    IXsvProvider
    属性。在同一类的构造函数中,将该属性设置为将返回“真实”读取器的默认提供程序。此接口只有一个方法,
    GetXsvReader(字符串文本)
  • 在测试类中,使用ParseCSV函数新建该类,然后注入一个IXsvProvider,它返回“dummy”
    IXsvReader
    ,只要您尝试使用该方法,它就会抛出异常

您应该使用
控制反转
并将依赖项注入控制器,而不是在控制器操作中创建依赖项。这样,您可以模拟读者,让它抛出一个except

我将用
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();
    }
}
现在,您可以在测试时使用mock
ICsvReader
,它将引发异常


此外,您应该只测试一个方法。如果你的方法有依赖项,你应该传递它们,而不是创建它们,这样你就可以只测试该方法中的代码,而不是它创建的类。

我通过传递null来解决这个问题,就像juharr在评论中推荐的那样。

+1用于测试代码如何处理故障。您可以按当前的编写方式将
csvText
@juharr的
null
传递给它,这是可行的,但它不是一个非常通用的解决方案。如果他想让空字符串的状态码与无效语法的状态码不同,那该怎么办。@克里夫尼主义者则必须更改代码并添加相应的测试。@juharr我不知道我怎么会不想到空字符串。我想我当时正忙着做一根长长的假绳子。不过,这起了作用。如果你把它作为一个答案,我会接受的。非常感谢!
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();
    }
}