为归档函数fs创建单元测试

问题描述 投票:1回答:3

我有以下功能正在按预期工作。现在我想为它创建单元测试。问题是我正在使用文件系统,我无法弄清楚如何使用一些模拟或任何其他解决方案。知道如何在Go中完成这项工作吗?我应该真的创建一个文件然后检查单元测试吗?我担心在某些系统中它会起作用而某些系统会中断(winodos / mac / linux)

这是工作功能:

func Zipper(src string,artifact string,target string) error {

    zf, err := os.Create(artifact)
    if err != nil {
        return err
    }
    defer zf.Close()

    ziper := zip.NewWriter(zf)
    defer ziper.Close()

    fileInfo, err := os.Stat(src)
    if err != nil {
        return err
    }

    var bs string
    if fileInfo.IsDir(); len(target) > 0 {
        bs = target
    } else {
        bs = filepath.Base(src)
    }

    if bs != "" {
        bs += "/"
    }

    filepath.Walk(src, func(path string, info os.FileInfo, err error) error {
        if err != nil {
            return err
        }

        if info.IsDir() {
            return nil
        }

        header, err := zip.FileInfoHeader(info)
        if err != nil {
            return err
        }

        if bs != "" {
            header.Name = filepath.Join(strings.TrimPrefix(path, bs))
        }

        header.Method = zip.Deflate

        writer, err := ziper.CreateHeader(header)
        if err != nil {
            return err
        }

        file, err := os.Open(path)
        if err != nil {
            return err
        }
        defer file.Close()
        _, err = io.Copy(writer, file)
        return err
    })

    return err
}

我读了下面的内容,但在我的情况下How to mock/abstract filesystem in go?没什么帮助

unit-testing go filesystems zip archive
3个回答
3
投票

测试依赖于文件系统的函数的最简单方法是在每个测试周围添加一些设置和拆除,在运行测试之前将必要的文件放在适当的位置,然后在运行测试后将其删除。

func TestZipper(t *testing.T) {
    // Create temporary files
    defer func() {
        // Clean up temporary files
    }()
    t.Run("group", func(t *testing.T) { // This is necessary so the above defer function doesn't run too soon
        // your actual tests
    })
}

3
投票

我知道“不访问文件系统”是许多人对“单元测试”定义的一部分。如果你的职业不是在寻找和捍卫定义:忘记这个限制。文件系统访问快速而精细,go工具甚至将名为“testdata”的文件夹视为特殊:这些文件夹应包含在测试期间使用的测试数据。

Go(和他们的用户)在区分“单元”和“集成”测试方面并不是很迂腐。看一下如何测试这些东西的stdlib。编写相关测试比在fs访问上获得幼稚更重要。 (请注意,文件系统和数据库在技术上是外部系统,但在现实生活中,如果没有文件系统,则无法编译Go代码,因此将测试与此“外部系统”隔离是荒谬的。)


0
投票

好吧,您可能会寻找一种以安全的方式操作文件系统或在其他地方寻找解决方案的方法。这个功能有什么责任?它应该准备一个zip文件还是写入文件系统?

我建议你应该从这个函数中取出文件创建并将函数更改为:

func Zipper(src string, dst io.Writer, target string) error {
    ziper := zip.NewWriter(dst)
    defer ziper.Close()

这样,出于测试目的,您可以提供简单的缓冲区,而在生产中使用您心爱的文件系统!

© www.soinside.com 2019 - 2024. All rights reserved.