代码之家  ›  专栏  ›  技术社区  ›  cupakob

如何模拟请求。请求在戈兰

  •  1
  • cupakob  · 技术社区  · 5 年前

    我在用 github.com/aws/aws-sdk-go/aws/request 要获得预签名的URL,我需要将文件上传到AWS中的S3 bucket。我现在正在写测试,因为我需要模仿 func (r *Request) Presign(expire time.Duration) . request.Request 是一个结构,而不是一个接口,所以我不知道,我怎么能模仿它。

    2 回复  |  直到 5 年前
        1
  •  3
  •   Jonas G. Drange    5 年前

    这不是直接回答你的问题,但它可能会完全消除问题的基础。

    Go中的一个好处是,您可以使用接口轻松地隔离依赖项。如果需要测试的代码部分正在使用 Presign 间接地,测试是微不足道的。

    即创建一个接口

    type HigherLevelAws interface {
        Upload(file string) error
    }
    

    在代码中使用这个接口,以及 Upload . 然后你可以很容易地用例如 https://godoc.org/github.com/stretchr/testify/mock

    实际的实现是这样的

    type ActualAwsImpl struct {
        aws *aws.Client
    }
    
    func (a *ActualAwsImpl) Upload(file string) error {
        aws.Presign...
    }
    

    这允许您测试代码的业务部分,但当然,仍然保留未测试的代码 ActualAwsImpl .然而,这个未测试的代码可以通过在AWS SDK本身中进行单元测试和集成测试来保证工作。 不管怎样,在我的组织中,我们使用在Docker中运行的假AWS服务(例如 https://github.com/gliffy/fake-s3 )

        2
  •  0
  •   fiskeben    5 年前

    您可以直接为函数创建接口,如下所示:

    type presigner interface {
        Presign(expire time.Duration) (string, error)
    }
    

    如果在一个单独的函数中实现逻辑, presigner 作为这样的参数(调用 依赖注入 ):

    func Upload(p presigner, files string) error {
        // ...
        res, err := p.Presign(someduration)
        if err != nil {
            return err
        }
        // and so on
    }
    

    然后很容易在测试中模拟-只需实现 预置器 接口并具有 Presign 函数返回期望值:

    type presignerMock struct {}
    
    func (p *presignerMock) Presign(d time.Duration) (string, error) {
        return "yay", nil
    }
    

    要测试不同的方案,可以将字段添加到 presignerMock 并将它们返回到您的实现中:

    type presignerMock {
        res string
        err error
    }
    
    func (p *presignerMock) Presign(d time.Duration) (string, error) {
        return p.res, p.err
    }