ITNEXT

ITNEXT is a platform for IT developers & software engineers to share knowledge, connect, collaborate, learn and experience next-gen technologies.

Follow publication

Yet another tool to mock interfaces in Go

Roman Budnikov
ITNEXT
Published in
3 min readNov 27, 2018

As a powerful tool, unit tests can give the ability to check every aspect of the code behavior. If you keep in mind an idea about the need for code testing, you will always write sustainable and maintainable code. Well designed code that depends on abstractions is easy to test, so code testability also can serve as an indicator of its quality.

If you have already tried to test code in Go, you probably know how useful interfaces can be. Go standard library provides you with a bunch of interfaces that you’re able to use in your code and most of them contain just a single method.

Go also has a supplementary framework created to help mock interfaces and a bunch of other community-driven packages that share similar functionality. Most of them give the ability to generate a struct that implements a given interface; this is very useful if an interface is large or it embeds other interfaces. But isn’t it too much when an interface has a single method?

The most amazing part about interfaces in Go is that they’re satisfied implicitly. Any type satisfies an interface simply by providing methods whose signature matches the interface declaration. This type could be even a function and if you’re familiar with the package net/http you might have already seen one of these types also called adapters.

As you can see, adapter itself is a function type with the same signature as the interface method declaration and it implements an interface by calling itself in the corresponding method. This adapter allows implementing Handler by any function with the appropriate signature. It comes as a generic tool to mock interfaces and looks very handy in table driven tests. For example, here’s the code that should be tested:

With the usage of the adapter, unit tests might look something like this:

Writing such adapters can be really annoying, so I’ve decided to write a tool for their automatic generation and called it adapt, this tool generates an adapter for a specified interface and prints it in the output. All you need is to pass a package name and an interface name to generate it.

$ adapt io Reader
type readerFunc func([]byte) (int, error)

func (f readerFunc) Read(p []byte) (int, error) {
return f(p)
}

You also can call adapt inside a package folder to generate an adapter for some of the package interfaces.

$ cd $GOPATH/src/github.com/x/execute Doer
$ adapt Doer
type doerFunc func() (int, error)

func (f doerFunc) Do() (int, error) {
return f()
}

It comes with a handy vim plugin which gives an ability to generate anadapter inside the vim.

Hopefully, you will find it useful.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

Published in ITNEXT

ITNEXT is a platform for IT developers & software engineers to share knowledge, connect, collaborate, learn and experience next-gen technologies.

No responses yet

Write a response