golang / protobuf

Go support for Google's protocol buffers
BSD 3-Clause "New" or "Revised" License
9.8k stars 1.58k forks source link

structpb.Struct.MarshalJSON is not consistent #1628

Closed zchenyu closed 4 months ago

zchenyu commented 4 months ago

I was running Go unit tests that seem to fail depending on the run / machine. It seems the way MarshalJSON handles spaces is inconsistent. Sometimes it outputs

{"x":"1","y":2}

and sometimes

{"x":"1", "y":2}

But I haven't figured out exactly what causes one or the other yet. Is there a way to make it consistent?

cybrcodr commented 4 months ago

That is intended. The MarshalJSON method uses the protojson.Marshal func underneath. And the description mentions ...

Do not depend on the output being stable. Its output will change across different builds of your program, even when using the same version of the protobuf module.

It's best not to compare JSON strings. Note that there is also no standard in the ordering of JSON fields.

zchenyu commented 4 months ago

Makes sense. Makes it a bit annoying to use in unit tests (e.g. mocks), but I'll figure it out.

puellanivis commented 4 months ago

You can use cmp.Compare and protocmp to test the semantics of the protobuf messages, rather than testing indirectly their serialization.

zchenyu commented 4 months ago

The issue we have is that we pass the serialized JSON to a mocked function. e.g.

mockClient.On("Foo", `{"x": 1}`)

So it's not just a simple assertion on the proto value.