例如,当我使用 gomock 测试使用 DynamoDB 的代码时,如下所示:
mockDynamoDB := awsmock.NewMockDynamoDBAPI(ctrl)
mockDynamoDBClient.EXPECT().PutItemWithContext(gomock.Any(),
gomock.Any() // Here I should use a custom matcher for comparing PutItemInput
).Return(&dynamodb.PutItemOutput{...}, nil).Times(1)
// do something which will internally call PutItemWithContext
为了避免到处使用
gomock.Any()
,我想我应该为PutItemInput
实现一个匹配器,但是这似乎有点困难,因为PutItemInput
与序列化的Item map[string]*AttributeValue
很复杂,我需要像这样一一比较,但是我不喜欢这个实现。
func (piim dynamodbPutItemInputEqualMatcher) Matches(x interface{}) bool {
input, ok := x.(*dynamodb.PutItemInput)
if !ok {
return false
}
if input.TableName != nil && piim.expectedInput.TableName != nil && *input.TableName != *pie.expectedInput.TableName {
return false
}
for attributeName, attributeValue := range input.Item {
exptectedAttributeValue, ok := piim.expectedInput.Item[attributeName]
if !ok {
return false
}
if attributeValue.N != nil && exptectedAttributeValue.N != nil && *attributeValue.N != *exptectedAttributeValue.N {
return false
}
if attributeValue.S != nil && exptectedAttributeValue.S != nil && *attributeValue.S != *exptectedAttributeValue.S {
return false
}
if attributeValue.BOOL != nil && exptectedAttributeValue.BOOL != nil && *attributeValue.BOOL != *exptectedAttributeValue.BOOL {
return false
}
if attributeValue.NULL != nil && exptectedAttributeValue.NULL != nil && *attributeValue.NULL != *exptectedAttributeValue.NULL {
return false
}
if attributeValue.B != nil || attributeValue.NS != nil || attributeValue.SS != nil || attributeValue.BS != nil || attributeValue.L != nil || attributeValue.M != nil {
return false
}
}
return true
}
DynamoDB 还有其他 API,如
GetItem
、ScanPages
等。我需要为每种类型的输入结构实现自定义匹配器。
我们有更好的方法将 gomock 与 AWS 结合使用吗?谢谢。
这似乎是过度使用模拟的一个例子。您将代码的实现细节泄漏到测试中,并且仅当您完全按照编写代码的方式使用模拟时,测试才有效,这使得重构变得不可能。
您不会测试是否对 DynamoDB 进行了正确的调用(为此您必须重新实现 DynamoDB),但如果您正在执行正在执行的调用 - 当它们错误时,您就会也必须修复你的测试。
因此,您在这里要做的就是返回预期结果以查看您的代码是否正常工作,并且仅当您的模拟不足并收到意外查询时才出错 - 这是您的模拟的问题,而不是您的代码的问题。
您的模拟不应该也无法验证所有参数 - 如果不重新实现 DynamoDB 或严格限制有效调用集以至于只有当前实现有效,这是不可能的。