unit-testing - 包含源和目标的 zip 文件夹

标签 unit-testing go zip

我使用以下代码将一些文件夹压缩到给定路径,我目前面临的问题是我需要将一些包含内容的文件夹压缩到特定目标而不是在同一目录中

例如

路径中的文件夹 来源

"/Users/i03434/go/src/zdf/BUILD"

目标

"/Users/i03434/go/src/zdf/app/info.zip"

目前我尝试添加新路径[2],但没有帮助,知道怎么做吗?

这就是全部代码

func zipit(params ...string) error {

    zipfile, err := os.Create(params[1])
    if err != nil {
        return err
    }
    defer zipfile.Close()

    archive := zip.NewWriter(zipfile)
    defer archive.Close()

    info, err := os.Stat(params[0])
    if err != nil {
        return err
    }

    var baseDir string
    if info.IsDir(); len(params) > 2 {
        baseDir = params[2]
    } else {
        baseDir = filepath.Base(params[0])
    }

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

    filepath.Walk(params[0], 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 baseDir != "" {
            header.Name = filepath.Join(strings.TrimPrefix(path, baseDir))
        }

        header.Method = zip.Deflate

        writer, err := archive.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
}

zip 的逻辑按预期工作,zip 应该符合 jar 规范

最佳答案

用于测试:

您可以传递一个模拟变量 zipFile这暗示了 io.Writer 接口(interface),作为函数的参数 zipit并将其与测试中的预期数据进行比较。
此外,您还需要目标中的一组已知文件,以便将其与模拟中的值进行比较。

Refer this for testing io.Writer

测试代码:

用特定值 source 创建的压缩文件的字符串值& newBaseDir应该事先知道并存储在want中.

func TestZipIt(t *testing.T) {

    source := ""
    newBaseDir := ""

    var zipFileMock bytes.Buffer
    if err := zipit(zipFileMock, source, newBaseDir); err != nil {
        t.Fatalf("zipit() returned an error: %s", err)
    }

    got := b.String()

    // want is the value of the zipped file as a string
    want := ...

    if got != want {
        t.Errorf("zipit() test failed")
        // t.Errorf("zipit() = %q, want %q", got, want)
    }
}

程序代码:

func main() {
    ...
    // params[0] is source
    // params[1] is destination
    // params[2] is newBaseDirectory

    zipfile, err := os.Create(destination)
    if err != nil {
        // handle error
    }
    defer zipfile.Close()

    if err = zipit(zipfile, source, newBaseDir); err != nil {
        // handle error
    }
    ...
}

func zipit(zipFile io.Writer, source, newBaseDir string) error {

    archive := zip.NewWriter(zipfile)
    defer archive.Close()

    info, err := os.Stat(source)
    if err != nil {
        return err
    }

    var baseDir string
    if info.IsDir() {
        baseDir = filepath.Dir(source)
    }

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

    filepath.Walk(source, 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 baseDir != "" {
            header.Name = filepath.Join(newBaseDir, strings.TrimPrefix(path, baseDir))
        }

        header.Method = zip.Deflate

        writer, err := archive.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
}

原始答案:

有几件事需要考虑。

  • 您需要使用 filepath.Dir 而不是 filepath.Base . Base 给出路径的最后一个元素而不是基本目录。

  • if info.IsDir(); len(params) > 2 {只检查条件 len(params) > 2 , info.IsDir()已评估但未在任何地方使用。

引用:If with a short statement format in Go [1] [2]

应该是

if info.IsDir() {
    if len(params) > 2 {
        ...
    } else {
        ...
    }
}
  • 如果我对您的要求的理解是正确的。旧的基本路径需要从文件头和 替换为 param[2] 的值(如果可用)或假设我们维护一个相对文件结构(如果它是空的)。

变化:

var baseDir string
if info.IsDir(); len(params) > 2 {
    baseDir = params[2]
} else {
    baseDir = filepath.Base(params[0])
}

应该是

    var baseDir, newBaseDir string
    if info.IsDir() {
        baseDir = filepath.Dir(params[0])
        if len(params) > 2 {
            newBaseDir = params[2]
        }
    }

header.Name = filepath.Join(strings.TrimPrefix(path, baseDir))
变成
header.Name = filepath.Join(newBaseDir, strings.TrimPrefix(path, baseDir))

关于unit-testing - 包含源和目标的 zip 文件夹,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50725437/

相关文章:

java - Mockito - 模拟具体类

c - 如何使用CMOCKA框架运行c单元测试用例?

php - 如何在没有完整路径的情况下压缩文件夹

c# - Visual C# 找不到我的 Ionic Zip .dll 文件

python - 如何在 App Engine 中读取 Google Storage 中的 zip 文件?

unit-testing - NUnit 的 log4Net 问题(已尝试 v2.5.7、2.5.2、2.4.8、2.4.7)

javascript - QUnit 模拟自动完成

go - Golang 中的安全关闭连接

go - vendor 是标准方法还是过时的方法?

concurrency - 为什么这段 Go 代码会死锁?