3 回答
TA贡献1845条经验 获得超8个赞
这不是直接回答你的问题,但它可能会完全消除问题的基础。
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)对此进行测试。
TA贡献1869条经验 获得超4个赞
我不得不模拟 S3 命令的请求。代码如下:
req, result := r.s3.ListObjectsV2Request(&s3.ListObjectsV2Input{
Bucket: aws.String(configs.Settings.S3Bucket),
})
err := req.Send()
Mock 函数必须返回一个请求对象
func (m *mockS3ProviderClient) ListObjectsV2Request(input *s3.ListObjectsV2Input) (req *request.Request, output *s3.ListObjectsV2Output) {
err := input.Validate()
req = &request.Request{
HTTPRequest: &http.Request{},
Error: err,
}
output = &s3.ListObjectsV2Output{
Contents: []*s3.Object{
{Key:aws.String("File1")},
{Key:aws.String("File2")},
},
}
return req, output
}
TA贡献1831条经验 获得超4个赞
您可以直接为该函数创建一个接口,如下所示:
type presigner interface {
Presign(expire time.Duration) (string, error)
}
如果您在一个单独的函数中实现您的逻辑,该函数将 apresigner作为参数,如下所示(称为依赖注入):
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
}
- 3 回答
- 0 关注
- 155 浏览
添加回答
举报