2条回答 默认 最新
- douzhan8395 2018-10-08 08:05关注
There is no ready solution for this in the standard library, but it's not that hard to do it yourself.
What we need is this
http.File
interface:type File interface { io.Closer io.Reader io.Seeker Readdir(count int) ([]os.FileInfo, error) Stat() (os.FileInfo, error) }
Please note that we can utilize
bytes.Reader
to do the heavy task, as that alone implementsio.Reader
andio.Seeker
.io.Closer
can be a noop, andReaddir()
may returnnil, nil
as we're mocking a file not a directory, itsReaddir()
won't even be called.The "hardest" part is to mock
Stat()
to return a value that implementsos.FileInfo
.Here's a simple mocked
FileInfo
:type myFileInfo struct { name string data []byte } func (mif myFileInfo) Name() string { return mif.name } func (mif myFileInfo) Size() int64 { return int64(len(mif.data)) } func (mif myFileInfo) Mode() os.FileMode { return 0444 } // Read for all func (mif myFileInfo) ModTime() time.Time { return time.Time{} } // Return anything func (mif myFileInfo) IsDir() bool { return false } func (mif myFileInfo) Sys() interface{} { return nil }
And with that we have everything to create our mocked
http.File
:type MyFile struct { *bytes.Reader mif myFileInfo } func (mf *MyFile) Close() error { return nil } // Noop, nothing to do func (mf *MyFile) Readdir(count int) ([]os.FileInfo, error) { return nil, nil // We are not a directory but a single file } func (mf *MyFile) Stat() (os.FileInfo, error) { return mf.mif, nil }
Example using it (try it on the Go Playground):
data := []byte{0, 1, 2, 3} mf := &MyFile{ Reader: bytes.NewReader(data), mif: myFileInfo{ name: "somename.txt", data: data, }, } var f http.File = mf _ = f
本回答被题主选为最佳回答 , 对您是否有帮助呢?解决 1无用