Skip to content
This repository was archived by the owner on Jun 27, 2023. It is now read-only.
This repository was archived by the owner on Jun 27, 2023. It is now read-only.

support proto.Message in Eq() #477

@ebilling

Description

@ebilling

Actual behavior
Protobufs generated using google.golang.org/protobuf/cmd/protoc-gen-go are not being reliably matched by the gomock Matcher.

Expected behavior
The default matcher for gomock should use the proto.Equal() function when a protobuf is passed as an argument.

To Reproduce Steps to reproduce the behavior

  1. Generate protobufs with latest protoc-gen-go from google.golang.org/protobuf/cmd/protoc-gen-go. It create a mutex in the protobuf which is likely causing the problem.
  2. Create two separate protobufs of equal content as the proto being matched and the proto being sent.
  3. Pass one of the protos to the command being mocked and the other as the proto to match against in the gomock EXPECT.

Additional Information

  • gomock mode (reflect or source): source
  • gomock version or git ref: aff3767
  • golang version: go1.15
  • proton-gen-go version: v1.22.0

Triage Notes for the Maintainers

For my personal use, I've created a proto matcher.

import "github.com/golang/protobuf/proto"

// ProtoMatcher is used along with gomock.EXPECT() statements. Protobufs can sometimes fail to match with a standard matcher
// ex: myService.EXPECT().Command(gomock.Any(), NewProtoMatcher(request)).Return(response, nil).AnyTimes()
type ProtoMatcher struct {
        proto.Message
}

// NewProtoMatcher returns a matcher suitable for use in gomock.Select()
// ex: mockDBService.EXPECT().Select(gomock.Any(), NewProtoMatcher(onboardResourcesRequest)).Return(selectOnboardResourcesResponse, nil).AnyTimes()
func NewProtoMatcher(p proto.Message) *ProtoMatcher {
        return &ProtoMatcher{
                Message: p,
        }
}

// Matches returns true if v is a protobuf and the contents match the one in the ProtoMatcher. Returns false if v is not a proto.Message
func (p ProtoMatcher) Matches(v interface{}) bool {
        vp, ok := v.(proto.Message)
        if !ok {
                return false
        }
        return proto.Equal(vp, p.Message)
}

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions