【问题标题】:How to mock/abstract filesystem in go?如何在 go 中模拟/抽象文件系统?
【发布时间】:2021-10-21 01:49:09
【问题描述】:

我希望能够将我的 go 应用程序发出的每次写入/读取记录到底层操作系统,并且(如果可能的话)将 FS 完全替换为仅驻留在内存中的 FS。

有可能吗?如何?也许有现成的解决方案?

【问题讨论】:

    标签: filesystems mocking go


    【解决方案1】:

    这直接来自 Andrew Gerrand 的10 things you (probably) don't know about Go

    var fs fileSystem = osFS{}
    
    type fileSystem interface {
        Open(name string) (file, error)
        Stat(name string) (os.FileInfo, error)
    }
    
    type file interface {
        io.Closer
        io.Reader
        io.ReaderAt
        io.Seeker
        Stat() (os.FileInfo, error)
    }
    
    // osFS implements fileSystem using the local disk.
    type osFS struct{}
    
    func (osFS) Open(name string) (file, error)        { return os.Open(name) }
    func (osFS) Stat(name string) (os.FileInfo, error) { return os.Stat(name) }
    

    为此,您需要编写代码以采用fileSystem 参数(可能将其嵌入到其他类型中,或者让nil 表示默认文件系统)。

    【讨论】:

    • 这看起来很有希望,但是直接调用os.Open 呢?分配fs 变量会“默默地”影响它们吗?
    • @canni:不,不会影响直接调用。如果这就是你想要的,我认为你将不得不在链接器上玩花样,而我自己从未尝试过。
    • 这个实现非常聪明,但是所有的“文件”都是零,这使得进行某些类型的测试变得困难。 IE。如果您有一个文件作为结构或文件映射的一部分,则无法测试正确的文件是否映射到正确的结构或映射键。
    【解决方案2】:

    对于那些希望在测试期间解决模拟文件系统问题的人,请查看 @spf13 的 Afero 库 https://github.com/spf13/afero。它完成了公认答案所做的一切,但具有更好的文档和示例。

    【讨论】:

    • afero 库的基于内存的文件系统(用于测试)非常宽松。一些函数返回一个错误,但该错误将始终为零。
    • @Bren 我们将 Afero 用于我们的生产代码,而不仅仅是用于测试。您能否进一步解释一下错误为零的含义?如果您认为行为不正确,可能最好在 github repo 上提出问题。
    • 它似乎不是io/fs 的替代品。 github.com/spf13/afero/issues/325
    【解决方案3】:

    您可以使用testing/fstest 包:

    package main
    import "testing/fstest"
    
    func main() {
       fs := fstest.MapFS{
          "hello.txt": {
             Data: []byte("hello, world"),
          },
       }
       data, err := fs.ReadFile("hello.txt")
       if err != nil {
          panic(err)
       }
       println(string(data) == "hello, world")
    }
    

    https://godocs.io/testing/fstest

    【讨论】:

    • 可以这样添加目录:fstest.MapFS{"tmp": {Mode: fs.ModeDir}}.
    【解决方案4】:

    仅仅因为这个问题在谷歌上搜索这个问题时弹出的频率很高:

    我不知道记录读取和写入,但对于仅驻留在内存中的文件系统,我找到了blang/vfs。我没有在生产中使用过,它说它是 alpha 并且接口可能会改变。需要您自担风险使用它。

    我想你可以实现它来记录读取和写入。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-09
      相关资源
      最近更新 更多