amazon-web-services - How do I write unit test aws-sdk-go-v2 dynamodb implementation
问题描述
I am still grasping go-interfaces and I can mock the WaitUntilTableExists func. But unable to mock PutItemRequest.
Here's my main.go snippet
func MyPutItem(d mydata, client dynamodbiface.DynamoDBAPI) error {
input := &dynamodb.PutItemInput{
....
}
req := client.PutItemRequest(input)
result, err := req.Send()
log.Println(result)
return err
}
main_test.go snippet
type mockDynamoDBClient struct {
dynamodbiface.DynamoDBAPI
}
func (m *mockDynamoDBClient) PutItemRequest(input *dynamodb.PutItemInput) dynamodb.PutItemRequest {
// Most probably this is where I need your help
}
func TestStoreInDynamoDB(t *testing.T) {
var mockClient = new(mockDynamoDBClient)
d := mydata{}
result := DynampDBPutItem(d, mockClient)
t.Log(result)
}
解决方案
以您为例,您可以直接在模拟中进行断言
type mockDynamoDBClient struct {
t *testing.T
expected *dynamodb.PutItemInput
response *dynamodb.PutItemOutput
dynamodbiface.DynamoDBAPI
}
func (m *mockDynamoDBClient) PutItemRequest(input *dynamodb.PutItemInput) dynamodb.PutItemOutput {
// some kind of equality check
if !reflect.DeepEqual(m.expected, input) {
t.Errorf(...// some error message)
}
return m.response
}
这个例子的主要问题是:
t *testing.T
,expected *dynamodb.PutItemInput
并且响应response *dynamodb.PutItemOutput
都需要在感觉混乱的结构内。
相反,您可以使用匿名函数来执行此操作:
type mockDynamoDBClient struct {
f func(input *dynmaodb.PutItemInput) *dynamodb.PutItemOutput
dynamodbiface.DynamoDBAPI
}
func (m *mockDynamoDBClient) PutItemRequest(input *dynamodb.PutItemInput) dynamodb.PutItemOutput {
return m.f(input)
}
现在在测试代码中,您可以更好地使用模拟结构:
m := &mockDynamoDBClient{
f: func(input *dynamodb.PutItemInput) *dynamodb.PutItemOutput {
// assertions on input
// return mock responses
}
}
根据评论编辑:
您还应该考虑使您的MyPutItem
函数依赖于可能的最小接口。如果您只需要访问该PutItemRequest
方法,那么您可以为该方法创建自己的接口并在MyPutItem
type MyDynamoPutter interface {
func (c *DynamoDB) PutItemRequest(input *PutItemInput) PutItemRequest
}
然后在MyPutItem
你可以使用你自己的界面:
func MyPutItem(d mydata, client MyDynamoPutter) error {
input := &dynamodb.PutItemInput{
....
}
req := client.PutItemRequest(input)
result, err := req.Send()
log.Println(result)
return err
}
这减少了您需要模拟的表面积!
推荐阅读
- ios - 如何使用 Atom 解决 .pbxproj 合并冲突?
- javascript - 是否可以在 HTML 页面上复制 .js 文件的内容以保存 HTTP 请求?
- node.js - 在 Amazon Lightsail 上安装 Strapi
- c# - 如何检测 PDF 中的损坏
- linux-kernel - EXT4的data=journal模式能否避免用户数据丢失?
- c++ - 尝试将用户输入存储到数组中
- xamarin.forms - Xamarin.Forms 等效于 UWP 的 VisualTreeHelper
- reactjs - Jhipster 根据用户角色动态添加按钮
- tensorflow - 哪种模型可以将日常照片分类为用餐/人物/风景而不是特定对象?
- r - R:在数据框中的每个级别内随机子集行