Golang Godog REST API 测试失败

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

Golang Godog REST API Test fails

问题

过去两周我一直在研究GODOG,这是一个类似于Golang的黄瓜行为驱动开发(BDD)工具。我觉得它非常有趣,最近我花了更多时间编写我的REST API的测试。最近,我一直无法通过一个测试。这个测试涉及一个JSON结构,其中包含子JSON。我正在按照以下链接中的示例进行测试:

https://github.com/DATA-DOG/godog/tree/master/examples/api

我有一个结构体:

type Status struct {
    ErrorCode string `json:"ERROR_CODE"`
    ErrorText string `json:"ERROR_TEXT"`
}

type OutputResponse1 struct {
    Status Status `json:"STATUS"`
}

type OutputResponse2 struct {
    Status Status `json:"STATUS"`
    Config json.RawMessage `json:"CONFIG"`
}

一个字节类型的变量:

var responseByte []byte

还有两种不同类型的输出响应:

//--------------1

responseByte, _ = json.Marshal(OutputResponse1{
    Status: Status{
        ErrorCode: "-2",
        ErrorText: "Config was not found",
    },
})

//------------2
responseByte, _ = json.Marshal(&OutputResponseSuccess{
    Status: Status{
        ErrorCode: "0",
        ErrorText: "",
    },
    Config: json.RawMessage(body),
})

json.Rawmessage是来自另一个源的内容,格式如下:

{
    "binaryVersion": "1.0.0",
    "configVersion": "1.1.1"
}

现在在功能文件中,我测试了以下内容:

//--------------1

并且响应应该匹配以下JSON:

{
    "STATUS": {
        "ERROR_CODE": "-2",
        "ERROR_TEXT": "Config was not found"
    }
}

这个测试通过了。

第二个测试涉及到了json.RawMessage

并且响应应该匹配以下JSON:

{
    "STATUS": {
        "ERROR_CODE": "0",
        "ERROR_TEXT": " "
    },
    "CONFIG": {
        "binaryVersion": "1.0.0",
        "configVersion": "1.1.1"
    }
}

这个测试失败了,尽管GODOG的输出与期望的完全相同。

------------------------GODOG测试的实际输出---------------------------

并且响应应该匹配以下JSON:

{"STATUS":{"ERROR_CODE":"0","ERROR_TEXT":" "},"CONFIG":{"binaryVersion":"1.0.0","configVersion":"1.1.1"}}

期望的JSON与实际的不匹配:

{"STATUS":{"ERROR_CODE":"0","ERROR_TEXT":" "},"CONFIG":{"binaryVersion":"1.0.0","configVersion":"1.1.1"}}

--- 失败的场景:

有人建议我去掉前导和尾随的空格,所以我尝试了:

bytes.TrimSpace(responseByte)

但还是没有成功。有人遇到同样的问题吗?

英文:

For past 2 weeks I have been looking into GODOG, a cucumber like bdd for golang. I found it very interesting and recently I am spending more time on writing a test for my REST API(s). Recently, I am continiuosly fialing to pass one of my test. This one includes a JSON struct that has childen JSON(s) inside itself. Also I am following exact example found at following link for my test:

https://github.com/DATA-DOG/godog/tree/master/examples/api

I have a struct like:

type Status struct {
    ErrorCode 	string	`json:"ERROR_CODE"`
    ErrorText  	string	`json:"ERROR_TEXT"`
}

type OutputResponse1 struct {
    Status Status `json:"STATUS"`
}

type OutputResponse2 struct {
    Status Status `json:"STATUS"`
    Config json.RawMessage `json:"CONFIG"`
}

A byte type variable:

var responseByte []byte

And two different kind of output response:

//--------------1

responseByte, _ = json.Marshal(OutputResponse1{
	Status: Status{
		ErrorCode: "-2",
		ErrorText:  "Config was not found",
	},
})

//------------2
responseByte, _ = json.Marshal(&OutputResponseSuccess{
		Status: Status{
			ErrorCode: "0",
			ErrorText:  " ",},
		Config: json.RawMessage(body),
})

The json.Rawmessage is something coming from another source which looks like:

 {
      "binaryVersion":"1.0.0",
      "configVersion":"1.1.1"
 }

Now in feature file I have tested out something like this:

 //--------------1

 And the response should match json:
 
    {
      "STATUS": {
         "ERROR_CODE": "-2",
         "ERROR_TEXT": "Config was not found"
      }
    }

THIS TEST PASS

The second one being one with json.RawMessage

And the response should match json:

 {
      "STATUS": {
          "ERROR_CODE":"0",
          "ERROR_TEXT":" "
      },
      "CONFIG":{
          "binaryVersion":"1.0.0",
          "configVersion":"1.1.1"
      }
 }

NOW THIS ONE FAILS, EVEN THOUGH THE GODG OUTPUT HAS THE ACTUAL AND EXPECTED SAME TO SAME

------------------------Acutal output of godog test---------------------------

 And the response should match json:
 
 
 {"STATUS":{"ERROR_CODE":"0","ERROR_TEXT":" "},"CONFIG":      {"binaryVersion":"1.0.0","configVersion":"1.1.1"}}
 

 Expected json does not match actual:
 {"STATUS":{"ERROR_CODE":"0","ERROR_TEXT":" "},"CONFIG":     {"binaryVersion":"1.0.0","configVersion":"1.1.1"}}
 
 --- Failed scenarios:

Someone from the godog also advised me to get rid of leading and trailing whitespace, so I even did

bytes.TrimSpace(responseByte)

still no luck.

Anyone facing the same problem?

答案1

得分: 1

不确定这是否能解决你的问题,但如果你使用的是Go1.7或更低版本,可以尝试将Config字段的类型设置为*json.RawMessage。因为在Go 1.8之前,json.RawMessageMarshaJSON方法是在指针接收器上定义的,而不是值接收器,这导致json.RawMessage的值被编码为Base64字符串字节。

type OutputResponse2 struct {
    Status Status `json:"STATUS"`
    Config *json.RawMessage `json:"CONFIG"`
}

raw := json.RawMessage(body)
responseByte, err := json.Marshal(&OutputResponseSuccess{
        Status: Status{
            ErrorCode: "0",
            ErrorText:  " ",
        },
        Config: &raw,
})
if err != nil {
    // ...
}
英文:

Not sure if this will solve your issue, but if you're on Go1.7 or less then try using *json.RawMessage as the Config field's type. Because Go's pre 1.8 json.RawMessage had its MarshaJSON method defined on the pointer receiver as opposed to the value receiver which caused json.RawMessage values to be encoded as strings bytes in base64.

type OutputResponse2 struct {
    Status Status `json:"STATUS"`
    Config *json.RawMessage `json:"CONFIG"`
}

raw := json.RawMessage(body)
responseByte, err := json.Marshal(&OutputResponseSuccess{
        Status: Status{
            ErrorCode: "0",
            ErrorText:  " ",
        },
        Config: &raw,
})
if err != nil {
    // ...
}

答案2

得分: 1

我是godog的作者。在你提供的示例中,它逐个比较字节并打印出实际结果,直到最后一个匹配的字节。

现在来说说Go语言中的json.Marshal。当它将一个map编组为json时,它会对map键进行排序。有了这个认识,如果我们重新编码预期和实际的json响应,那么我们可以确保如果匹配的话,它应该产生相同的字节切片,无论你以什么顺序放置预期的对象键。

英文:

I'm the author of godog. Currently in the example you linked, it compares bytes one by one and prints the actual result up to the last byte it matched.

Now about the json.Marshal in go. When it marshals a map to json, it sorts map keys and having that in mind if we re-encode both expected and actual json responses, then we can be certain that it should produce the same byte slice if it matches, no matter in which order you placed expected object keys.

huangapple
  • 本文由 发表于 2017年3月17日 22:46:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/42860487.html
匿名

发表评论

匿名网友

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

确定