我有一个连接到 AWS S3 并获取文件的程序。我想为它编写一些测试,但更一般地说,我想知道如何在 Golang 中进行这些模拟。我知道有一些库可以创建模拟,但如果我没记错的话,我读到有人建议只使用标准库进行单元测试是最好的方法。
那么,您将如何测试这样的函数?
func (s S3Input) Sample(key string) ([]byte, error) {
var buf []byte
waBuf := aws.NewWriteAtBuffer(buf)
_, err := s.Downloader.Download(
waBuf,
&s3.GetObjectInput{
Bucket: aws.String(s.Bucket),
Key: aws.String(key),
},
)
if err != nil {
return nil, err
}
return buf, nil
}
Run Code Online (Sandbox Code Playgroud)
谢谢!
一种方法是在您的结构中注入依赖项,例如:
type S3Inputer interface {
NewWriteAtBuffer(buf []byte) *aws.WriteAtBuffer
String(v string) *string
}
type S3Input struct {
newWriteAtBufferFunc func(buf []byte) *aws.WriteAtBuffer
stringFunc func(v string) *string
}
func (s *S3Input) NewWriteAtBuffer(buf []byte) *WriteAtBuffer {
return s.newWriteAtBufferFunc(buf)
}
func (s *S3Input) String(v string) *string {
return s.stringFunc(v)
}
func (s S3Input) Sample(key string) ([]byte, error) {
var buf []byte
waBuf := s.NewWriteAtBuffer(buf)
_, err := s.Downloader.Download(
waBuf,
&s3.GetObjectInput{
Bucket: s.String(s.Bucket),
Key: s.String(key),
},
)
if err != nil {
return nil, err
}
return buf, nil
}
func main() {
s := &S3Input{
StringFunc: aws.String,
NewWriteAtBufferFunc: aws.NewWriteAtBuffer,
}
// ...
}
Run Code Online (Sandbox Code Playgroud)
这允许您将这些功能替换为您想要进行测试的任何功能,而无需任何测试框架。
然后,测试函数看起来像这样:
func (s S3Input) TestSample(t *testing.T) {
s3Mock := &S3Input{
StringFunc: (func (v string) *string {
return nil
}),
NewWriteAtBufferFunc: (func (buf []byte) *aws.WriteAtBuffer {
return nil
}),
}
res, err := s3Mock.Sample(...) //
// asserts & error checks
}
Run Code Online (Sandbox Code Playgroud)
您可以通过创建S3InputMock类型而不是重用基本类型来改进它,两者都将实现S3Inputer接口并且您的模拟可以具有允许它帮助您进行测试的属性。例如,它可以计算一个函数被调用的次数,存储它接收到的参数,根据你为更容易测试而设置的属性,它的方法有不同的行为,等等。