英文:
UUID field within Go Pact consumer test
问题
我目前正在研究将 Pact 测试添加到我的 Go 代码中,但我在处理 UUID 字段类型时遇到了困难。我有以下结构体,用于将 API 的响应反序列化:
import (
"github.com/google/uuid"
)
type Foo struct {
ID uuid.UUID `json:"id"`
Name string `json:"name"`
Description string `json:"description"`
}
现在,当我尝试编写我的消费者测试时,代码看起来像这样:
pact.
AddInteraction().
Given("A result exists").
UponReceiving("A request to get all results").
WithRequest(dsl.Request{
Method: "get",
Path: dsl.String("/v1"),
}).
WillRespondWith(dsl.Response{
Status: 200,
Headers: dsl.MapMatcher{"Content-Type": dsl.String("application/json")},
Body: dsl.Match(&Foo{}),
})
问题是,模拟的响应如下所示,它试图将字节数组放入 "id" 字段中,我猜测这是因为在幕后它是以字节数组的形式存储的。
{
"id": [
1
],
"name": "string",
"description": "string"
}
有人遇到过这个问题吗?最好的解决方法是什么?我唯一能想到的解决方案是将我的模型更改为字符串,然后在代码中手动转换为 UUID。
英文:
I'm currently looking at adding Pact testing into my Go code, and i'm getting stuck on how to deal with field types of UUID.
I have the following struct, which I use to deserialise a response from an API to
import (
"github.com/google/uuid"
)
type Foo struct {
ID uuid.UUID `json:"id"`
Name string `json:"name"`
Description string `json:"description"`
}
Now, when I try and write my consumer test, it looks something like this
pact.
AddInteraction().
Given("A result exists").
UponReceiving("A request to get all results").
WithRequest(dsl.Request{
Method: "get",
Path: dsl.String("/v1"),
}).
WillRespondWith(dsl.Response{
Status: 200,
Headers: dsl.MapMatcher{"Content-Type": dsl.String("application/json")},
Body: dsl.Match(&Foo{}),
})
The problem now, is the mocked response comes through as below, where it tries to put an array of bytes in the "id" field, I'm assuming since behind the scenes that is what the google/uuid library stores it as.
{
"id": [
1
],
"name": "string",
"description": "string"
}
Has anyone encountered this? And what would be the best way forward - the only solution I can see is changing my model to be a string, and then manually convert to a UUID within my code.
答案1
得分: 1
你目前无法以这种方式使用Match
函数,因为它会递归非原始结构,尽管可以通过结构标签来覆盖这种行为。你能否提出一个功能请求?
最简单的方法是不使用Match
方法,而是以通常的方式手动表达合同细节。
英文:
You currently can't use the Match
function this way, as it recurses non primitive structures, albeit it should be possible to override this behaviour with struct tags. Could you please raise a feature request?
The simplest approach is to not use the Match
method, and just manually express the contract details in the usual way.
答案2
得分: 0
uuid.UUID的内部表示是type UUID [16]byte
,但UUID的JSON表示是字符串。
var u uuid.UUID
u, _ = uuid.Parse("f47ac10b-58cc-0372-8567-0e02b2c3d479")
foo1 := Foo{u, "n", "d"}
res, _ := json.Marshal(foo1)
fmt.Println(string(res))
{
"id": "f47ac10b-58cc-0372-8567-0e02b2c3d479",
"name": "n",
"description": "d"
}
然后加载序列化的[]byte
var foo Foo
json.Unmarshal(res, &foo)
英文:
The internal representation of uuid.UUID is type UUID [16]byte
but json representation of UUID is string
var u uuid.UUID
u, _ = uuid.Parse("f47ac10b-58cc-0372-8567-0e02b2c3d479")
foo1 := Foo{u, "n", "d"}
res, _ := json.Marshal(foo1)
fmt.Println(string(res))
{
"id": "f47ac10b-58cc-0372-8567-0e02b2c3d479",
"name": "n",
"description": "d"
}
and then load marshaled []byte
var foo Foo
json.Unmarshal(res, &foo)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论