如何使用dynamodb数据库进行API功能测试?

问题描述 投票:0回答:1

我想对POST api进行功能测试。在该方法中,它将在生产环境中调用DynamoDB客户端。我已经启动了Docker容器供DynamoDB对其进行测试。但是,当我测试此代码时,它实际上调用了生产客户端DynamoDB。

router.HandleFunc("/v1/fxm/worklog", api.SaveFxmWorklog).Methods(PostMethod)

方法:


func SaveFxmWorklog(w http.ResponseWriter, r *http.Request) {
    var rb entity.FxmWorklogDetails
    err := json.NewDecoder(r.Body).Decode(&rb)
    if err != nil {
        log.Error().Err(err).Msgf("Failed to parse the fxm worklog request %s", util.ToJSON(rb))
        util.ErrorResponse(w, err.Error(), http.StatusBadRequest)
        return
    }
    log.Info().Msgf("Save fxm worklog request received for order %s", rb.OrderId)
    response, err := service.FxmService.SaveFxmWorklogEvent(rb)
    if err != nil {
        log.Error().Err(err).Msgf("Failed to save fxm worklog event %s", util.ToJSON(rb))
        util.ErrorResponse(w, err.Error(), http.StatusInternalServerError)
        return
    }
    w.WriteHeader(response.HTTPStatusCode)
    _ = json.NewEncoder(w).Encode(response)
}

var FxmService FxmWorklogService

type FxmWorklogService interface {
    SaveFxmWorklogEvent(event entity.FxmWorklogDetails) (*response.BaseResponse, error)
}

type FxmWorklogServiceImpl struct {
    fxmRepo fxm.Repository
}

func init() {
    FxmService = FxmWorklogServiceImpl{fxmRepo: fxm.NewRepo()}
}

func (f FxmWorklogServiceImpl) SaveFxmWorklogEvent(event entity.FxmWorklogDetails) (*response.BaseResponse, error) {
    err := f.fxmRepo.SaveFxmWorklogDetails(&event)
    if err != nil {
        log.Error().Err(err).Msgf("Failed to save fxm worklog event for order %s", event.OrderId)
        return nil, err
    }
    return &response.BaseResponse{Status: util.SuccessStatusMessage, StatusCode: util.SuccessStatusCode, HTTPStatusCode: http.StatusOK}, nil
}
type Repository interface {
    SaveFxmWorklogDetails(worklogDetails *entity.FxmWorklogDetails) error
    UpdateFxmWorklogDetails(worklogDetails *entity.FxmWorklogDetails) error
    GetEditOrderFxmWorklogDetails(orderId string) (*entity.FxmWorklogDetails, error)
}
var (
    tableName = "delivery-assistance.fxm_worklog_events"
    key       = "orderId"
)

type Repo struct {
    Db persistence.DBOperation
}

func NewRepo() *Repo {
    return &Repo{Db: persistence.NewDB()}
}

func (r *Repo) SaveFxmWorklogDetails(worklogDetails *entity.FxmWorklogDetails) error {
    return r.Db.PutItem(tableName, worklogDetails)
}

func (r *Repo) UpdateFxmWorklogDetails(worklogDetails *entity.FxmWorklogDetails) error {
    return r.Db.PutItem(tableName, worklogDetails)
}

func (r *Repo) GetEditOrderFxmWorklogDetails(orderId string) (*entity.FxmWorklogDetails, error) {
    var output []entity.FxmWorklogDetails
    err := r.Db.GetItemsWithSameKeyAndStringValue(tableName, key, orderId, &output)
    if err != nil {
        log.Error().Err(err).Msgf("Failed to get fxm worklog details for order %s", orderId)
        return nil, err
    }
    if len(output) > 0 {
        for _, event := range output {
            if event.Action == util.EditOrderAction && event.ExceptionName == util.EditOrderException {
                return &event, nil
            }
        }
    }
    return nil, nil
}
// This struct extends the DBOperation interface for DynamoDB implementation
type DynamoDB struct {
    client *dynamodb.DynamoDB
}

// DynamoDB Constructor
func NewDB() *DynamoDB {
    return &DynamoDB{dynamodb2.Client()}
}

//This function Creates a new item, or replaces an old item with a new item.
func (db *DynamoDB) PutItem(tableName string, data interface{}) error {
    av, err := dynamodbattribute.MarshalMap(data)
    if err != nil {
        log.Error().Err(err).Msgf("Failed to convert to attribute value %s", util.ToJSON(data))
        return err
    }
    input := &dynamodb.PutItemInput{
        Item:      av,
        TableName: aws.String(tableName),
    }

    log.Info().Msgf("Dynamo db endpoint: %d", db.client.Endpoint)
    _, err = db.client.PutItem(input)
    if err != nil {
        log.Error().Err(err).Msgf("Error calling put item")
        return err
    }
    return nil
}

DynamoDB客户端:

var (
    client *dynamodb.DynamoDB
)

func init() {
    sess, err := session.NewSession(&aws.Config{
        Region: aws.String(config.Client.GetString("AWS_CREDS.region")),
        Credentials: credentials.NewStaticCredentialsFromCreds(credentials.Value{
            AccessKeyID:     config.Client.GetString("AWS_CREDS.access_key_id"),
            SecretAccessKey: config.Client.GetString("AWS_CREDS.secret_access_key"),
        }),
        Endpoint: aws.String(config.Client.GetString("AWS_CREDS.endpoint")),
    })
    if err != nil {
        log.Error().Err(err).Msgf("Failed to connect to aws")
    }
    client = dynamodb.New(sess)
}

func Client() *dynamodb.DynamoDB {
    return client
}

功能测试:

func Test_Functional_Managers(t *testing.T) {
    if testing.Short() {
        t.Skip("Skipping Functional Test")
        return
    }
    testContainers, err := util.SetupContainers()
    if err != nil {
        t.Errorf("ErrorInitializing Container, error = %v", err)
    }
    log.Info().Msgf("http://%s:%s", testContainers.Dynamo.Host(), testContainers.Dynamo.Port())
    SaveFxmWorklogTest(t, testContainers)
}
func SaveFxmWorklogTest(t *testing.T, containers *util.Containers) {
    var FxmWorklogDetails = `{"orderId":"1231","worklogType":"RECOVERY","businessLine":"Food","serviceLine":"FOOD","action":"ORDER_EDIT","exceptionName":"ITEM_OUT_OF_STOCK","system":"VENDOR","subSystem":"Delivery","createdAt":1234567890}`
    var r io.Reader
    r = strings.NewReader(FxmWorklogDetails)
    url := fmt.Sprintf("http://%s:%s", containers.Dynamo.Host(), containers.Dynamo.Port())
    config.Client.SetString("AWS_CREDS.access_key_id", "random")
    config.Client.SetString("AWS_CREDS.secret_access_key", "random")
    config.Client.SetString("AWS_CREDS.endpoint", url)

    if err := containers.Dynamo.CreateTable(test_data.CreateTableRequest); err != nil {
        t.Errorf("Error Creating table, err = %v", err)
    }
    req, _ := http.NewRequest("POST", "/v1/fxm/worklog", r)
    w := httptest.NewRecorder()
    api.SaveFxmWorklog(w, req)
}

TestContainer:

type Containers struct {
    Dynamo *dynamo.Dynamo
}

func SetupContainers() (*Containers, error) {
    dynamoContainer, err := dynamo.NewContainer()
    if err != nil {
        return nil, err
    }
    return &Containers{
        Dynamo:    dynamoContainer,
    }, nil
}

测试日志:

=== RUN   Test_Functional_Managers
2020/06/12 13:21:35 Starting container id: 5a987112c28d image: quay.io/testcontainers/ryuk:0.2.3
2020/06/12 13:21:35 Waiting for container id 5a987112c28d image: quay.io/testcontainers/ryuk:0.2.3
2020/06/12 13:21:35 Container is ready id: 5a987112c28d image: quay.io/testcontainers/ryuk:0.2.3
2020/06/12 13:21:35 Starting container id: 691016e5a216 image: amazon/dynamodb-local
2020/06/12 13:21:35 Waiting for container id 691016e5a216 image: amazon/dynamodb-local
2020/06/12 13:21:36 Container is ready id: 691016e5a216 image: amazon/dynamodb-local
{"level":"info","time":"2020-06-12T13:21:36+05:30","message":"http://localhost:32773"}
{"level":"info","time":"2020-06-12T13:21:37+05:30","message":"Endpoint: http://localhost:32773"}
{"level":"info","time":"2020-06-12T13:21:37+05:30","message":"Save fxm worklog request received for order 1231"}
{"level":"info","time":"2020-06-12T13:21:37+05:30","message":"Dynamo db endpoint: %!d(string=http://dynamodb.ap-southeast-1.amazonaws.com)"}
{"level":"error","error":"ResourceNotFoundException: Requested resource not found","time":"2020-06-12T13:21:37+05:30","message":"Error calling put item"}
{"level":"error","error":"ResourceNotFoundException: Requested resource not found","time":"2020-06-12T13:21:37+05:30","message":"Failed to save fxm worklog event for order 1231"}
{"level":"error","error":"ResourceNotFoundException: Requested resource not found","time":"2020-06-12T13:21:37+05:30","message":"Failed to save fxm worklog event {\"orderId\":\"1231\",\"worklogType\":\"RECOVERY\",\"businessLine\":\"Food\",\"serviceLine\":\"FOOD\",\"action\":\"ORDER_EDIT\",\"exceptionName\":\"ITEM_OUT_OF_STOCK\",\"system\":\"VENDOR\",\"subSystem\":\"Delivery\",\"createdAt\":1234567890}"}
--- PASS: Test_Functional_Managers (2.10s)
PASS
go amazon-dynamodb functional-testing
1个回答
0
投票

如果包中不存在,则可以实现TestMain(m * testing.M)函数,并更改AWS的凭证:


func TestMain(m *testing.M) {
    sess, err := session.NewSession(&aws.Config{
        Region: aws.String(config.Client.GetString("AWS_CREDS_TEST.region")),
        Credentials: credentials.NewStaticCredentialsFromCreds(credentials.Value{
            AccessKeyID:     config.Client.GetString("AWS_CREDS_TEST.access_key_id"),
            SecretAccessKey: config.Client.GetString("AWS_CREDS_TEST.secret_access_key"),
        }),
        Endpoint: aws.String(config.Client.GetString("AWS_CREDS_TEST.endpoint")),
    })
    if err != nil {
        log.Error().Err(err).Msgf("Failed to connect to aws")
    }
    client = dynamodb.New(sess)

    exitVal := m.Run()

    os.Exit(exitVal)
}

© www.soinside.com 2019 - 2024. All rights reserved.