You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为dynamodbattribute.UnmarshalMap编写抛错Mock测试

解决方案:抽象反序列化依赖实现Mock测试

要在不修改UpdateItem返回结果的前提下测试UnmarshalMap报错的场景,核心思路是把硬编码的dynamodbattribute.UnmarshalMap调用抽象为可注入的依赖,这样测试时就能用Mock实现直接抛出错误。

步骤1:定义反序列化接口

先创建一个接口封装UnmarshalMap的行为,让业务代码依赖这个接口而非具体实现:

import (
    "github.com/aws/aws-sdk-go-v2/service/dynamodb/types"
    "github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue"
)

// DynamoDBUnmarshaler 定义DynamoDB属性反序列化的接口
type DynamoDBUnmarshaler interface {
    UnmarshalMap(attrs map[string]types.AttributeValue, out interface{}) error
}

步骤2:实现默认的反序列化器

对应生产环境的默认实现,直接包装官方的UnmarshalMap函数:

// DefaultUnmarshaler 生产环境使用的默认反序列化器
type DefaultUnmarshaler struct{}

func (u *DefaultUnmarshaler) UnmarshalMap(attrs map[string]types.AttributeValue, out interface{}) error {
    return attributevalue.UnmarshalMap(attrs, out)
}

步骤3:修改业务函数,注入依赖

更新update函数,把DynamoDBUnmarshaler作为参数传入(也可以通过结构体成员注入,根据你的代码结构调整):

func update(ddbClient, unmarshaler DynamoDBUnmarshaler) {
    updatedItem, err := ddbClient.updateItem(...)
    if err != nil {
        // 处理updateItem的错误逻辑
        return
    }

    obj := new(MyCustomObj)
    err = unmarshaler.UnmarshalMap(updatedItem.Attributes, &obj)
    if err != nil {
        fmt.Println("Error while unmarshalling")
    }
}

步骤4:编写Mock测试用例

用Mock框架(比如github.com/stretchr/testify/mock)实现DynamoDBUnmarshaler接口,让它直接返回预设错误:

import (
    "fmt"
    "testing"
    "github.com/stretchr/testify/mock"
)

// MockUnmarshaler 用于测试的反序列化Mock
type MockUnmarshaler struct {
    mock.Mock
}

func (m *MockUnmarshaler) UnmarshalMap(_ map[string]types.AttributeValue, _ interface{}) error {
    args := m.Called()
    return args.Error(0)
}

func TestUpdate_UnmarshalFailure(t *testing.T) {
    // 初始化你已有的DDB Client Mock
    mockDDB := // 你的DDB Client Mock实例,确保updateItem返回正常结果

    // 初始化Mock反序列化器,预设返回错误
    mockUnmarshaler := new(MockUnmarshaler)
    mockUnmarshaler.On("UnmarshalMap").Return(fmt.Errorf("mock unmarshal failure"))

    // 调用业务函数
    update(mockDDB, mockUnmarshaler)

    // 验证错误处理逻辑是否触发(比如检查日志输出,或用断言验证行为)
    // 示例:如果用日志捕获,可以断言日志中包含指定错误信息
    // assert.True(t, logOutputContains("Error while unmarshalling"))
    
    // 验证Mock的方法被正确调用
    mockUnmarshaler.AssertExpectations(t)
}

为什么这种方式可行?

  • 避免了修改UpdateItem返回的Attributes,不会影响其他依赖正常Attributes的测试场景
  • 通过依赖注入解耦了业务代码与具体的反序列化实现,让测试可以精准控制反序列化环节的错误
  • 符合Go语言的接口依赖设计原则,代码扩展性更好

内容的提问来源于stack exchange,提问作者NoSleepDev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 18:33:39