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

Go编写Pact消费者测试时dsl.Match函数报错问题求助

Pact Go消费者测试:解决"match: unhandled type: interface {}"错误

问题背景

使用Go编写Pact消费者测试,对接PHP提供方服务,定义预期响应后运行测试触发panic:

--- FAIL: TestGetDeviceConfiguration (1.79s)
panic: match: unhandled type: interface {} [recovered]
        panic: match: unhandled type: interface {}

错误原因

  1. 重复匹配器嵌套:将已通过dsl.Like处理的对象再次用dsl.Match包装,导致Pact无法识别嵌套的匹配器类型。
  2. 匹配器结构错误:dsl.Like与dsl.MapMatcher的嵌套方式不当,使内部结构被解析为interface{}类型,触发未处理的类型错误。

解决方案

1. 移除多余的dsl.Match调用

dsl.Like本身就是合法的匹配器,直接赋值给Response.Body即可,无需额外用dsl.Match包裹。

2. 调整响应对象的匹配器结构

简化嵌套层级,确保每个结构都能被Pact正确识别:

  • 顶层用dsl.Like定义整体响应结构
  • 内部关联数组直接用dsl.MapMatcher定义键值匹配规则,或用dsl.Like(map[string]interface{})模拟灵活结构

修正后的完整代码

func TestGetDeviceConfiguration(t *testing.T) {
    // Create Pact client
    pact := &dsl.Pact{
        Consumer: "consumer",
        Provider: "provider",
        PactDir:  "./pacts",
    }

    defer pact.Teardown()

    // 修正后的响应对象定义
    deviceConfigurationResponse := dsl.Like(map[string]interface{}{
        "status": "success",
        "data": dsl.MapMatcher{
            "configuration": dsl.MapMatcher{
                "config1": dsl.String("value1"),
                "config2": dsl.String("value2"),
            },
            "undeploy_configuration": dsl.MapMatcher{
                "undeploy1": dsl.String("value3"),
                "undeploy2": dsl.String("value4"),
            },
            "meta_data": dsl.MapMatcher{
                "meta1": dsl.String("info1"),
                "meta2": dsl.String("info2"),
            },
            "undeploy_lora_app_key": dsl.String("example_undeploy_lora_app_key"),
        },
    })

    // Define the expected interaction with the provisioning-service
    value := "123456789"
    pact.
        AddInteraction().
        Given("Device configuration exists for the given device ID").
        UponReceiving("A request to get device configuration").
        WithRequest(dsl.Request{
            Method:  "GET",
            Path:    dsl.String(fmt.Sprintf("/api/prov/state/%s/configuration", value)),
            Headers: dsl.MapMatcher{"Accept": dsl.String("application/json")},
        }).
        WillRespondWith(dsl.Response{
            Status:  200,
            Headers: dsl.MapMatcher{"Content-Type": dsl.String("application/json")},
            Body:    deviceConfigurationResponse, // 移除dsl.Match包裹
        })

    // Test the OnSessionEstablished function
    var test = func() error {
        cache := new(CacheMock)
        deviceConfigGetter := new(DeviceConfigGetterMock)

        _, err := GetDeviceConfiguration(value)

        cache.AssertExpectations(t)
        deviceConfigGetter.AssertExpectations(t)

        return err
    }

    // Verify the interaction with the provider
    var err = pact.Verify(test)
    assert.NoError(t, err)
}

额外说明

如果需要允许PHP返回的关联数组包含额外字段,可以将内部的dsl.MapMatcher替换为dsl.Like(map[string]interface{}),示例:

"configuration": dsl.Like(map[string]interface{}{
    "config1": "value1",
    "config2": "value2",
}),

这种方式会匹配结构相似的任意关联数组,而非严格匹配定义的键值对。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 10:55:20