Функция модульного тестирования, которая открывает и читает файл - PullRequest
2 голосов
/ 31 мая 2019

Я работаю над обучением, использую простую программу, которая выполняет чтение некоторых файлов и работаю над добавлением модульного тестирования в мою программу.Я столкнулся с проблемой / вопросом, делая это.Я хочу выполнить модульное тестирование функции ниже, и мой вопрос в том, что функция берет имя файла, который затем открывается и обрабатывается.Во время тестирования я не хочу на самом деле передавать его реальным файлом.Мне интересно, это что-то, что я могу каким-то образом высмеять, чтобы я мог просто передать ему «фальшивый» файл и обработать его вместо этого?Спасибо!

func openAndReadFile(fileName string) [][]string {
    file, err := os.Open(fileName)
    if err != nil {
        fmt.Printf("Failed to read file: %s", fileName)
    }
    r := csv.NewReader(file)
    lines, err := r.ReadAll()
    if err != nil {
        log.Fatal(err)
    }
    return lines
}

Ответы [ 3 ]

5 голосов
/ 31 мая 2019

Вам необходимо провести рефакторинг своего кода и сделать его более подходящим для тестирования.

Вот как я бы это сделал:

func openAndReadFile(fileName string) [][]string {
    file, err := os.Open(fileName)
    if err != nil {
        fmt.Printf("Failed to open file: %s", fileName)
    }
    lines, err := readFile(file)
    if err != nil {
        fmt.Printf("Failed to read file: %s", fileName)
    }
    return lines
}

func readFile(reader io.Reader) ([][]string, error) {
    r := csv.NewReader(reader)
    lines, err := r.ReadAll()
    if err != nil {
        log.Fatal(err)
    }
    return lines, err
}

Тогда для тестирования вы можете просто использовать любую структуру данных, котораяреализует интерфейс io.reader.Например, я использую буфер байтов, но вы можете выбрать сетевое соединение:

func TestReadFile(t *testing.T) {
    var buffer bytes.Buffer
    buffer.WriteString("fake, csv, data")
    content, err := readFile(&buffer)
    if err != nil {
        t.Error("Failed to read csv data")
    }
    fmt.Print(content)
}
1 голос
/ 01 июня 2019

В показанной вами функции преобладают взаимодействия: взаимодействия с файловой системой и взаимодействия с читателем csv. Чтобы убедиться, что эти взаимодействия работают хорошо, вам в любом случае позже придется провести некоторое интеграционное тестирование с файловой системой и csv reader. Подумайте о том, какие ошибки вы надеетесь найти, и вы увидите, что ошибки более вероятны на уровне взаимодействия: правильный ли порядок файлов, или они должны быть наоборот? Действительно ли значение nil указывает на отсутствие ошибки? Вы должны дать больше аргументов для Open? и т.д.

Поэтому я бы не стал концентрироваться на юнит-тестировании этой функции. Однако эта функция является хорошим кандидатом для насмешки, чтобы упростить модульное тестирование окружающего кода. Таким образом, макет openAndReadFile для модульного тестирования окружающего кода и тестирования openAndReadFile с использованием интеграционного тестирования.

0 голосов
/ 01 июня 2019

Я бы настоятельно рекомендовал использовать интерфейс вместо строки имени файла, как рекомендуют другие ответы здесь, но если вы действительно должны это сделать, единственный способ, вероятно, с временным файлом . Решение использовать строковое имя файла заблокировало код для предположения, что что-то должно присутствовать в файловой системе, и возложило на себя ответственность за управление файлами.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...