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