如何在golang中模拟request.Request

时间:2019-01-21 07:17:29

标签: amazon-web-services go request mocking

我正在使用github.com/aws/aws-sdk-go/aws/request获取预先签名的URL,我需要将这些文件上传到AWS中的s3存储桶。我目前正在编写测试,为此我需要模拟func (r *Request) Presign(expire time.Duration)request.Request是一个结构,而不是一个接口,所以我不知道如何模拟它。

2 个答案:

答案 0 :(得分:4)

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

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)进行测试。

答案 1 :(得分:0)

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

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
}

然后在测试中轻松模拟-只需实现presigner接口并让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
}