ProtoEqual
is a custom matcher designed for comparing Protocol Buffer messages in Go.
It allows you to focus on the meaningful fields of protobuf messages and ignores internal fields such as
state
, sizeCache
, and unknownFields
, which are generated by the google.golang.org/protobuf
package.
- Protobuf-specific comparison: Uses
proto.Equal
to compare the actual content of protobuf messages, ignoring any internal state or metadata fields. - Seamless integration with Gomega: Works like other Gomega matchers for easy use in unit tests.
- Support for nested protobuf messages: Handles complex protobuf structures with nested messages.
To add the ProtoEqual
dependency to your project, you can reference this repository. Use the following
command to add it:
go get github.com/afritzler/protoequal
Make sure you also have the Protocol Buffers Go plugin installed if you're working with .proto
files.
You can install it using:
go get google.golang.org/protobuf
The ProtoEqual
matcher is used to compare Protocol Buffer messages within Gomega-based tests. It helps you
compare protobuf messages without worrying about internal fields added by the protobuf compiler.
Assume you have the following .proto
file defining Foo
and Qux
messages:
syntax = "proto3";
package api.v1;
option go_package = "github.com/afritzler/protoequal/test/api/v1";
// The Foo message with Bar, Baz fields and a nested message Qux.
message Foo {
string bar = 1; // Bar field
string baz = 2; // Baz field
Qux qux = 3; // Qux is a nested message
}
// The Qux message with Driver and Handle fields.
message Qux {
string driver = 1; // Driver field
string handle = 2; // Handle field
}
After generating the Go code using protoc
, you can now write tests comparing Foo
messages using ProtoEqual
.
Here is an example of how to use the ProtoEqual matcher in a test:
package matchers_test
import (
"testing"
"google.golang.org/protobuf/proto"
. "github.com/afritzler/protoequal"
"github.com/afritzler/protoequal/test/api/v1"
"github.com/onsi/gomega"
)
func TestProtoEqualMatcher(t *testing.T) {
g := gomega.NewWithT(t)
// Define two identical Foo messages
actualMessage := &test.Foo{
Bar: "foo-bar",
Baz: "foo-baz",
Qux: &test.Qux{
Driver: "foo-driver",
Handle: "foo-handle",
},
}
expectedMessage := &test.Foo{
Bar: "foo-bar",
Baz: "foo-baz",
Qux: &test.Qux{
Driver: "foo-driver",
Handle: "foo-handle",
},
}
// Use ProtoEqual to assert that actualMessage matches expectedMessage
g.Expect(actualMessage).To(ProtoEqual(expectedMessage))
}
Since ProtoEqual
uses proto.Equal
internally, it automatically handles nested messages. For example,
in the Foo
message, the nested Qux
message is compared as part of the overall structure.
When comparing protobuf messages directly in Go, the default equality check will include internal fields
generated by the Protobuf compiler (e.g., state
, sizeCache
). These fields are not relevant to the content
of the message and can cause tests to fail even when the message data is identical. ProtoEqual
solves this by
ignoring these internal fields and focusing only on the actual message content.
This project is licensed under the Apache 2.0 License. See the LICENSE file for details.