Filesystems 如何在go中模拟/抽象文件系统?

Filesystems 如何在go中模拟/抽象文件系统?,filesystems,mocking,go,Filesystems,Mocking,Go,我希望能够记录我的go应用程序向底层操作系统发出的每一次写/读操作,并且(如果可能的话)用只驻留在内存中的操作系统完全替换FS 可能吗?怎么用?也许有现成的解决方案?这是安德鲁·格兰德的: 要使其工作,您需要编写代码以获取文件系统参数(可能将其嵌入其他类型,或者让nil表示默认文件系统)。只是因为在谷歌搜索此问题时,这个问题会弹出很高: 我不知道如何记录读取和写入,但对于仅驻留在内存中的文件系统,我发现。我还没有在生产中使用,它说它是alpha,接口可能会改变。使用它的风险自负 我想您可以实现它

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


可能吗?怎么用?也许有现成的解决方案?

这是安德鲁·格兰德的:


要使其工作,您需要编写代码以获取
文件系统
参数(可能将其嵌入其他类型,或者让
nil
表示默认文件系统)。

只是因为在谷歌搜索此问题时,这个问题会弹出很高:

我不知道如何记录读取和写入,但对于仅驻留在内存中的文件系统,我发现。我还没有在生产中使用,它说它是alpha,接口可能会改变。使用它的风险自负


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

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

您可以使用
测试/fstest
包:

package main
import "testing/fstest"

func main() {
   m := fstest.MapFS{
      "hello.txt": {
         Data: []byte("hello, world"),
      },
   }
   b, e := m.ReadFile("hello.txt")
   if e != nil {
      panic(e)
   }
   println(string(b) == "hello, world")
}

这看起来很有希望,但是直接调用
os.Open如何?分配
fs
变量是否会“无声地”影响他们?@canni:不,它不会影响直接调用。如果这是你想要的,我想你必须在链接器上玩把戏,我自己从来没有尝试过。这个实现非常聪明,但是所有的“文件”都是零,这使得进行某些类型的测试非常困难。也就是说,如果您有一个文件作为结构或文件映射的一部分,则无法测试正确的文件是否映射到了正确的结构或映射键。@Paradiesstaub:afero库的基于内存的文件系统(用于测试的)非常宽松。有些函数返回一个错误,但该错误将始终为零。@Bren我们将Afero用于生产代码,而不仅仅用于测试。你能解释一下错误为零是什么意思吗?如果您认为行为不正确,最好在github回购协议上提交问题。
package main
import "testing/fstest"

func main() {
   m := fstest.MapFS{
      "hello.txt": {
         Data: []byte("hello, world"),
      },
   }
   b, e := m.ReadFile("hello.txt")
   if e != nil {
      panic(e)
   }
   println(string(b) == "hello, world")
}