打开和读取文件的单元测试功能

我正在学习如何使用一个简单的程序进行一些文件读取,并正在为我的程序添加单元测试。这样做时我遇到了一个问题/问题。我想对下面的函数进行单元测试,我的问题是该函数采用文件的名称,然后打开并处理该文件。在测试期间,我不想实际将真实文件传递给它。我想知道这是我可以以某种方式模拟的东西,以便我可以将它传递给一个“假”文件并让它处理它吗?谢谢!


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

}


大话西游666
浏览 169回答 3
3回答

临摹微笑

您需要重构您的代码并使其更适合测试。这是我会怎么做: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)}

缥缈止盈

您显示的功能主要由交互决定:与文件系统的交互以及与 csv 阅读器的交互。为确保这些交互工作良好,您以后无论如何都必须针对文件系统和 csv 阅读器进行一些集成测试。想想你希望找到哪些错误,你会发现错误更可能出现在交互层面:文件的顺序是正确的,还是应该相反?nil 真的是表示没有错误的值吗?您是否必须为 Open 提供更多论据?ETC。因此,我不会专注于对该功能进行单元测试。然而,这个函数是一个很好的候选者,可以模拟它使周围代码的单元测试更容易。因此,模拟openAndReadFile对周围代码进行单元测试,并openAndReadFile使用集成测试进行测试。

慕标5832272

我强烈建议使用接口而不是文件名字符串,就像这里推荐的其他答案一样,但如果你真的必须这样做,唯一的方法可能是使用临时文件。使用字符串文件名的决定已将代码锁定为假设文件系统上存在某些内容,并推入了文件管理的责任。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go