【问题标题】:How do I write unit test aws-sdk-go-v2 dynamodb implementation如何编写单元测试 aws-sdk-go-v2 dynamodb 实现
【发布时间】:2018-10-26 21:49:05
【问题描述】:

我仍在掌握 go-interfaces,我可以模拟 WaitUntilTableExists 函数。但无法模拟PutItemRequest

这是我的 ma​​in.go sn-p

func MyPutItem(d mydata, client dynamodbiface.DynamoDBAPI) error {
    input := &dynamodb.PutItemInput{
        ....
    }
    req := client.PutItemRequest(input)
    result, err := req.Send()
    log.Println(result)
    return err
}

ma​​in_test.go sn-p

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)
}

【问题讨论】:

    标签: amazon-web-services go aws-sdk aws-sdk-go


    【解决方案1】:

    以您为例,您可以直接在模拟中进行断言

    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.Texpected *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
    }
    

    这减少了您需要模拟的表面积!

    【讨论】:

    • 谢谢!但这不起作用,PutItemRequest 不满足接口(应该返回 dynamodb.PutItemRequest)。 iface 中的示例已过时(从旧版本复制),实际上还有更多内容:github.com/aws/aws-sdk-go-v2/issues/70
    【解决方案2】:

    像这样伪造 SDK:

    main_test.go

    type fakeDynamoDBClient struct {
        dynamodbiface.DynamoDBAPI
    }
    
    func (m *fakeDynamoDBClient) GetItemRequest(input *dynamodb.GetItemInput) dynamodb.GetItemRequest {
        return dynamodb.GetItemRequest{
            Request: &aws.Request{
                Data: &dynamodb.GetItemOutput{
                    Item: map[string]dynamodb.AttributeValue{
                        "count": dynamodb.AttributeValue{
                            N: aws.String("10"),
                        },
                    },
                },
            },
        }
    }
    
    func (m *fakeDynamoDBClient) PutItemRequest(input *dynamodb.PutItemInput) dynamodb.PutItemRequest {
        return dynamodb.PutItemRequest{
            Request: &aws.Request{
                Data: &dynamodb.PutItemOutput{},
            },
        }
    }
    
    func TestUpdateCount(t *testing.T) {
        err := UpdateCount(10, &fakeDynamoDBClient{})
        if err != nil {
            t.Error("Failed to update badge count on dynamodb", err)
        }
    }
    

    main.go

    func UpdateCount(count int, client dynamodbiface.DynamoDBAPI) error {
        ...
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-10-25
      • 2022-01-24
      • 1970-01-01
      • 2021-04-23
      • 2015-05-18
      • 1970-01-01
      相关资源
      最近更新 更多