Mok — thread-safe mocking library for Golang

Yuri Zinchenko
2 min readMay 30, 2024

--

Photo by NordWood Themes on Unsplash

Jonathan Hall came up with a very interesting idea on how to mock interfaces without using of third-party libraries. This approach can be briefly described as follows:

// Mock of the io.Reader interface.
type ReaderMock struct {
ReadFunc func(p []byte) (n int, err error)
}

func (m *ReaderMock) Read(p []byte) (n int, err error) {
return m.ReadFunc(p) // Here we use only one function for each method call.
}

Looks very nice and simple! However, when testing cmd-stream, it turned out that it is much more convenient to use a separate function for each method call, as well as to have multithreading support. This is how mok was born. Just a small example of how to use it:

  // Here we register several calls to the Read() method, and then call it
// several times as well. Each method call is just a function.
// If we want to register one function several times, we can use the
// RegisterN() method. This is especially useful when testing concurrent
// method invocations.
var (
reader = NewReaderMock().RegisterRead(func(p []byte) (n int, err error) {
p[0] = 1
return 1, nil
}).RegisterRead(func(p []byte) (n int, err error) {
p[0] = 2
p[1] = 2
return 2, nil
}).RegisterNRead(2, func(p []byte) (n int, err error) {
return 0, io.EOF
})
b = make([]byte, 2)
)
// In total, we have registered 4 calls to the Read() method.

// First call.
n, _ := reader.Read(b)
// We expect to read 1 byte.
assert.Equal(n, 1, t)
// ...

More details can be found at github.

--

--

No responses yet