Используя ваш пример, вы можете сделать свои утверждения прямо в макете
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
}
Это уменьшает площадь поверхности, которая вам нужна для макета!