Возможно ли провести модульное тестирование этой функции Go, в которой используется AWS SDK, без изменения параметров? - PullRequest
0 голосов
/ 21 мая 2018

Я новичок в Go и написал функцию, которая использует AWS Secrets Manager для извлечения секрета:

//Helper function to get secret from AWS Secret Manager
func getAWSSecrets() (secretMap map[string]string, err error) {
    // Create new AWS session in order to get db info from SecretsManager
    sess, err := session.NewSession()
    if err != nil {
        return nil, err
    }

    // Create a new instance of the SecretsManager client with session
    svc := secretsmanager.New(sess)

    //Get secret config values
    req, resp := svc.GetSecretValueRequest(&secretsmanager.GetSecretValueInput{
        SecretId: aws.String("my/secret/string"),
    })

    err = req.Send()
    if err != nil {
        return nil, err
    }

    ...
}

Мне нужно создать модульный тест для этой функции, и для этого мне нужноиздеваться над менеджером секретов AWS.Я обнаружил интерфейс Secrets Manager, который был создан AWS, чтобы помочь с модульным тестированием .В показанном примере диспетчер секретов AWS передается в тестируемую функцию, что облегчает его передачу в службу имитации.Это единственный способ успешно выполнить модульное тестирование функции?Или сервис может быть посмеян в функции, которую я имею выше?

1 Ответ

0 голосов
/ 21 мая 2018

Как говорится в комментариях, заставьте функцию вызывать метод и воспользуйтесь интерфейсом, который предоставляет AWS.

Я бы создал службу, подобную этой:

package service

type SecretService struct {
    AwsProvider aws.SecretsManagerAPI
}

func NewSecretService() (*SecretService, err) {
    // Create new AWS session in order to get db info from SecretsManager
    sess, err := session.NewSession()
    if err != nil {
        return nil, err
    }

    return &SecretService{
        AwsProvider: secretsmanager.New(sess),
    }, nil
}

func (s *SecretService) GetAWSSecrets() {
    req, resp := s.AwsProvider.GetSecretValueRequest(&secretsmanager.GetSecretValueInput{
        SecretId: aws.String("my/secret/string"),
    })

    err = req.Send()
    if err != nil {
        return nil, err
    }

    // More magic below ...
}

Таким образом, в тестах я мог передать любую пародию на SecretService, например:

func TestSecretService_GetAWSSecrets(t *testing.T) {
  service := &service.SecretService{
    AwsProvider: <use your mock here>
  }
}

Одно предостережение, я предполагаю, что макет должен реализовывать все методы SecretsManagerAPI, которые, как мне кажется,работайте по этому простому сценарию ... в любом случае вы можете создать свой собственный интерфейс внутри пакета сервиса, используя только подмножество методов, которые вы будете использовать, допустим, вы собираетесь использовать только GetSecretValueRequest и CreateSecret:

package service

type SecretProvider interface {
    CreateSecret(*secretsmanager.CreateSecretInput) (*secretsmanager.CreateSecretOutput, error)
    GetSecretValueRequest(*secretsmanager.GetSecretValueInput) (*request.Request, *secretsmanager.GetSecretValueOutput)
}

Измените службу:

type SecretService struct {
    AwsProvider SecretProvider
}

Теперь ваш макет должен только реализовывать только методы интерфейса SecretProvider.И, конечно же, AWS SecretsManager неявно реализует SecretProvider.

...