Golang:创建用于测试文件读取功能的临时目录

Posted

技术标签:

【中文标题】Golang:创建用于测试文件读取功能的临时目录【英文标题】:Golang: Creating temporary directory for testing a file reading function 【发布时间】:2021-12-25 21:45:46 【问题描述】:

我正在尝试为文件读取功能编写测试。该函数接受目录路径并开始扫描以对具有子目录的文件进行分类。

func FileScan(dir string) (map[string][]string, error) 
    var dataset = make(map[string][]string)

    files, err := ioutil.ReadDir(dir)
    if err != nil 
        return nil, err
    

    for _, file := range files 
        if file.IsDir() 
            dirFiles, err := ioutil.ReadDir(fmt.Sprintf("%s/%s", dir, file.Name()))
            if err != nil 
                return nil, err
            

            for _, dirFile := range dirFiles 
                if !dirFile.IsDir() 
                    dataset[file.Name()] = append(dataset[file.Name()], dirFile.Name())
                
            
        
    
    return dataset, nil

为了测试,我在测试文件旁边创建了一个临时目录,并在其中放置了一些子目录和文件,然后开始测试函数并通过 defer 调用清理函数以在测试后删除目录。

这是一个好习惯吗? ??? 或者最好传递[]fs.FileInfo 的数组而不是目录路径,这样我就可以在测试中实现一个模拟的FileInfo

【问题讨论】:

是的。这是一个很好的做法。您甚至可以签入测试目录和文件。无需创建和清理它们。 使用os.MkdirTemp 和/或os.CreateTemp 在测试中创建目录和/或文件是很常见的。旁注 - 您应该使用 os pkg 而不是 ioutil。见golang.org/doc/go1.16#ioutil 您可以在testdata 下创建一些测试文件/目录并将其作为源代码树的一部分。 我认为,一旦您可以避免使用文件系统,这是一种不好的做法。不接触文件系统时测试会更快。测试在无状态时不易出错。 【参考方案1】:

如果您修改代码的方式可以使用 https://pkg.go.dev/testing/fstest@go1.17.3#MapFS 旁注:it's recommended 使用 os.ReadDir 而不是 ioutil.ReadDir

这是一个对您的代码进行了最少修改的工作示例 (playground link):

package main

import (
    "fmt"
    "io/fs"
    "log"
    "path"
    "reflect"
    "testing/fstest"
)

func main() 
    var myFiles fstest.MapFS = make(map[string]*fstest.MapFile)
    myFiles["test_dir/i_am_a_file"] = &fstest.MapFile
    myFiles["test_dir/i_am_a_directory/add_me_to_map"] = &fstest.MapFile
    myFiles["test_dir/i_am_a_directory_too/add_me_to_map_too"] = &fstest.MapFile
    myFiles["test_dir/i_am_a_directory_too/and_me"] = &fstest.MapFile
    myFiles["test_dir/i_am_a_directory_too/do_not_add_me_to_map/"] = &fstest.MapFile
    m, err := FileScan(myFiles, "test_dir")
    if err != nil 
        log.Fatalln("Test failed:", err)
    
    expectedMap := map[string][]string
        "i_am_a_directory":     "add_me_to_map",
        "i_am_a_directory_too": "add_me_to_map_too", "and_me",
    

    if !reflect.DeepEqual(expectedMap, m) 
        log.Fatalf("m: expected  = %v, observed = %v", 2, expectedMap, m)
    
    fmt.Println("OK")


func FileScan(fileSystem fs.FS, dir string) (map[string][]string, error) 
    var dataset = make(map[string][]string)
    files, err := fs.ReadDir(fileSystem, dir)
    if err != nil 
        return nil, err
    
    for _, file := range files 
        if !file.IsDir() 
            continue
        
        dirFiles, err := fs.ReadDir(fileSystem, path.Join(dir, file.Name()))
        if err != nil 
            return nil, err
        
        for _, dirFile := range dirFiles 
            if dirFile.IsDir() 
                continue
            
            dataset[file.Name()] = append(dataset[file.Name()], dirFile.Name())
        

    
    return dataset, nil


【讨论】:

以上是关于Golang:创建用于测试文件读取功能的临时目录的主要内容,如果未能解决你的问题,请参考以下文章

Golang basic_leaming文件目录操作

Golang basic_leaming文件目录操作

Golang - 用于解析 yaml 文件并检查对象的单元测试

Golang 如何限制木马图片上传服务器

Golang 如何限制木马图片上传服务器

Viper--方便好用的Golang 配置库