Go Pact消费者测试中的UUID字段

huangapple go评论63阅读模式
英文:

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)

huangapple
  • 本文由 发表于 2021年9月24日 12:24:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/69309542.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定