Reputation: 51
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?
Upvotes: 0
Views: 1271
Reputation: 878
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.
Upvotes: 1
Reputation: 38223
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 {
// ...
}
Upvotes: 1