Сбой try/catch блок чтения CSV

Я тестирую свое приложение C#, которое анализирует CSV. Я нахожусь на 94% покрытия кода, потому что я не могу заставить его завершать работу блоков try/catch... Я использую CsvHelper из Nuget http://joshclose.github.io/CsvHelper

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 = "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 у меня есть раздел, обеспечивающий существование всех заголовков, и он терпит неудачу там, но в этом примере это должно произойти сбой во время чтения. Как заставить мой модульный тест провалиться? Любая помощь приветствуется! Заранее спасибо.

3 ответа

Решение

Я решил это, просто передав ему значение null, как рекомендовал Джухарр в комментариях.

Используйте шаблон поставщика и интерфейсы вместо конкретных типов, затем запустите свои модульные тесты, заменив фиктивные объекты, которые будут генерировать исключения.

В деталях:

  • Извлечь интерфейс IXsvReader от XsvReader
  • Внедрить новый конкретный экземпляр IXsvReader это бросает исключения на Read, Создайте один конкретный класс реализации для каждой ошибки, которую вы ожидаете обработать отдельно (в этом случае вам нужна только одна).
  • В классе, который содержит ParseCSV метод, иметь свойство для IXsvProvider это устанавливается. В конструкторе этого же класса установите для этого свойства поставщик по умолчанию, который будет возвращать "настоящего" читателя. Этот интерфейс имеет только один метод, GetXsvReader(string text)
  • В вашем тестовом классе создайте новый класс с помощью функции ParseCSV, а затем внедрите IXsvProvider(s), который возвращает ваш "фиктивный" 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 при тестировании, и это вызовет исключение.

Кроме того, вы должны когда-либо тестировать только один метод. Если у вашего метода есть зависимости, вы должны передавать их, а не создавать их, чтобы вы могли тестировать только код в этом методе, а не классы, которые он создает.

Другие вопросы по тегам