如何模拟/抽象文件系统?

can*_*nni 24 filesystems mocking go

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

可能吗?怎么样?也许有一个随时可用的解决方案?

Fre*_*Foo 35

这是直接来自安德鲁·格兰德的10件事你可能不知道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) }
Run Code Online (Sandbox Code Playgroud)

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

  • 我很想看到一个有效的代码示例. (7认同)
  • 这看起来很有希望,但是直接调用`os.Open`怎么样?分配`fs`变量会"默默地"影响它们吗? (2认同)

小智 22

您可以使用该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")
}
Run Code Online (Sandbox Code Playgroud)

https://godocs.io/testing/fstest

  • 可以像这样添加目录:`fstest.MapFS{"tmp": {Mode: fs.ModeDir}}`。 (3认同)
  • 您如何支持测试绝对路径? (3认同)
  • 请注意,用于测试的所有子目录不得是绝对路径。例如,这是不正确的: `fstest.MapFS{"/do/not/use/absolute/paths/no.txt": {}}` 这是正确的: `fstest.MapFS{"relative/path/with/no/ leading/slash/ok.txt": {}}` 我不小心添加了绝对路径,并且这些条目在测试中被省略。奇怪的是,添加了一个带有空“名称”的目录。 (2认同)

Rya*_*lls 20

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

  • @Bren,我们将 Afero 用于生产代码,而不仅仅是用于测试。您能更多地解释一下错误为零的含义吗?如果您认为行为不正确,最好在 github 存储库上提交问题。 (2认同)