matryer / moq

Interface mocking tool for go generate
http://bit.ly/meetmoq
MIT License
2k stars 127 forks source link
codegen golang mocking testing

moq logo build Go Report Card

Interface mocking tool for go generate.

What is Moq?

Moq is a tool that generates a struct from any interface. The struct can be used in test code as a mock of the interface.

Preview

above: Moq generates the code on the right.

You can read more in the Meet Moq blog post.

Installing

To start using latest released version of Moq, just run:

$ go install github.com/matryer/moq@latest

Note that Go 1.18+ is needed for installing from source. For using Moq with older Go versions, use the pre-built binaries published with Moq releases.

Usage

moq [flags] source-dir interface [interface2 [interface3 [...]]]
  -fmt string
        go pretty-printer: gofmt, goimports or noop (default gofmt)
  -out string
        output file (default stdout)
  -pkg string
        package name (default will infer)
  -rm
        first remove output file, if it exists
  -skip-ensure
        suppress mock implementation check, avoid import cycle if mocks generated outside of the tested package
  -stub
        return zero values when no mock implementation is provided, do not panic
  -version
        show the version for moq
  -with-resets
        generate functions to facilitate resetting calls made to a mock

Specifying an alias for the mock is also supported with the format 'interface:alias'

Ex: moq -pkg different . MyInterface:MyMock

NOTE: source-dir is the directory where the source code (definition) of the target interface is located. It needs to be a path to a directory and not the import statement for a Go package.

In a command line:

$ moq -out mocks_test.go . MyInterface

In code (for go generate):

package my

//go:generate moq -out myinterface_moq_test.go . MyInterface

type MyInterface interface {
    Method1() error
    Method2(i int)
}

Then run go generate for your package.

How to use it

Mocking interfaces is a nice way to write unit tests where you can easily control the behaviour of the mocked object.

Moq creates a struct that has a function field for each method, which you can declare in your test code.

In this example, Moq generated the EmailSenderMock type:

func TestCompleteSignup(t *testing.T) {

    var sentTo string

    mockedEmailSender = &EmailSenderMock{
        SendFunc: func(to, subject, body string) error {
            sentTo = to
            return nil
        },
    }

    CompleteSignUp("me@email.com", mockedEmailSender)

    callsToSend := len(mockedEmailSender.SendCalls())
    if callsToSend != 1 {
        t.Errorf("Send was called %d times", callsToSend)
    }
    if sentTo != "me@email.com" {
        t.Errorf("unexpected recipient: %s", sentTo)
    }

}

func CompleteSignUp(to string, sender EmailSender) {
    // TODO: this
}

The mocked structure implements the interface, where each method calls the associated function field.

Tips

License

The Moq project (and all code) is licensed under the MIT License.

Moq was created by Mat Ryer and David Hernandez, with ideas lovingly stolen from Ernesto Jimenez. Featuring a major refactor by @sudo-suhas, as well as lots of other contributors.

The Moq logo was created by Chris Ryer and is licensed under the Creative Commons Attribution 3.0 License.