如何模拟调用 io.Copy 的函数

试图模拟以下功能。它基本上从 S3 ( io.ReadCloser) 中获取一个对象并将其写入一个文件,该文件执行os.Open()时间较早 ( 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)

            }

        })

    }

}


明月笑刀无情
浏览 89回答 1
1回答

互换的青春

这是因为io.Copy直到 EOF 或错误才返回。将副本从 src 复制到 dst,直到在 src 上到达 EOF 或发生错误。它返回复制的字节数和复制时遇到的第一个错误(如果有)。成功的 Copy 返回 err == nil,而不是 err == EOF。因为 Copy 被定义为从 src 读取直到 EOF,所以它不会将 Read 的 EOF 视为要报告的错误。因此,如果您从 返回 EOF mockReadCloser.Read,它就不会再挂起。func (m mockReadCloser) Read(p []byte) (int, error) { return 0, io.EOF }这是因为 Read 被重复调用,直到没有更多内容可读 (EOF)。for {     nr, er := src.Read(buf)     ... }
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go