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 {}
错误原因
- 重复匹配器嵌套:将已通过
dsl.Like处理的对象再次用dsl.Match包装,导致Pact无法识别嵌套的匹配器类型。 - 匹配器结构错误:
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
相关产品推荐
相关产品推荐

