尝试模拟以下函数。它基本上从 S3 ( io.ReadCloser
) 获取一个对象并将其写入执行 os.Open()
的文件中。 d 较早 ( io.WriteCloser
)。
package main
import (
"io"
log "github.com/sirupsen/logrus"
)
func writeFile(destination io.WriteCloser, source io.ReadCloser) error {
defer destination.Close()
defer source.Close()
_, err := io.Copy(destination, source)
if err != nil {
log.WithFields(log.Fields{"desc": "unable to copy contents from s3 to blahblah"}).Error(err)
return err
}
return nil
}
我认为我已经非常接近了,但目前我的测试挂起并且从未错误/成功...我还意识到我可以通过 os.Stdout
到了目的地,但仍然遇到同样的问题。 io.Copy
内发生了一些事情。我想这是因为我试图将空数据复制到什么都没有?
package main
import (
"errors"
"io"
"reflect"
"testing"
)
type mockReadCloser struct {}
func (m mockReadCloser) Read(p []byte) (int, error) { return 0, nil }
func (m mockReadCloser) Close() error { return nil }
type mockWriteCloser struct{}
func (m mockWriteCloser) Close() error { return nil }
func (m mockWriteCloser) Write(b []byte) (n int, err error) { return 0, nil }
func Test_writeFile(t *testing.T) {
type args struct {
destination io.WriteCloser
source io.ReadCloser
}
tests := []struct {
name string
args args
wantErr bool
}{
{
name: "",
args: args{
destination: &mockWriteCloser{},
source: &mockReadCloser{},
},
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if err := writeFile(tt.args.destination, tt.args.source); (err != nil) != tt.wantErr {
t.Errorf("writeFile() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}
最佳答案
因为io.Copy直到 EOF 或错误才返回。
Copy copies from src to dst until either EOF is reached on src or an error occurs. It returns the number of bytes copied and the first error encountered while copying, if any.
A successful Copy returns err == nil, not err == EOF. Because Copy is defined to read from src until EOF, it does not treat an EOF from Read as an error to be reported.
因此,如果您从 mockReadCloser.Read
返回 EOF,它就不会再挂起。
func (m mockReadCloser) Read(p []byte) (int, error) { return 0, io.EOF }
这是因为 Read 被重复调用,直到没有更多内容可供读取 (EOF)。
for {
nr, er := src.Read(buf)
...
}
关于go - 如何模拟调用 io.Copy 的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72669429/