Here are some things I learned about testing in Golang that I want to remember. They’re not all related to one another.

Method Set

This is a simple way to mock a go interface (“object”):

type DummyJob struct {
    Job
}

DummyJob now implements Job, you can override whatever methods you need. This makes use of Methods Sets in Go.

This syntax felt a bit weird to me at first (why does this struct have a field that doesn’t have a type?) but turns out to be nice when you get used to it. You can add additional methods to the DummyJob interface as well.

Protobuf Serialization

If you need a serialized protobuf for test purposes, you can use proto.Marshal(my_proto_object) to get the user-readable string.

Generated Code for Protocol Buffers in Go

I’ve been so used to dealing with protobufs in C++ and python that learning yet another set of auto-generated code has felt a bit burdensome. But I do appreciate that protobufs generate idiomatic code for target languages. For quick reference, here’s go’s generated code reference.

And here is an example of defining a protocol buffer object in Go, with discrete examples for enums, string/int literals, and repeated fields.

notification := &mypb.Notification{
	Name: &enpb.EntityName{
		NameSpace: proto.String("some_namespace"),
		Name:      proto.String("some_name"),
	},
	Trigger: mypb.EventNotification_SUCCESS,
	FileNotification: &fnpb.FileNotification{
		FileLocation: &flpb.FileLocation{
			LocationBase: proto.String(""),
			FilePattern:  proto.String(""),
			NumShards:    proto.Int64(0),
		},
	},
	Userdata: proto.String("user data string"),
	Userdata: proto.String("other user data string"),

	EntityType: &etpb.EntityType{
		etpb.EntityType_EVENT.Enum(),
	},
	AuthorizeAs: &scpb.PrincipalProto{
		Scope: scpb.PrincipalProto_USER,
		User: &scpb.UserProto{
			UserID: proto.Int64(12345),
		},
	},
}
notificationBytes, err := proto.Marshal(notification)

Common errors I’ve had:

  • Forgotten commas within the proto lead to compilation errors.
  • Enum syntax is a bit tricky because generated code is kinda magical, look at examples.
  • Need to import protos for nested protos.