1. 程式人生 > >Meet Moq: Easily mock interfaces in Go

Meet Moq: Easily mock interfaces in Go

Meet Moq: Easily mock interfaces in Go

Moq is an Interface mocking tool for go generate — github.com/matryer/moq

In my recent talk about Idiomatic Go Tricks I talked about a testing technique that David Hernandez showed me where you can test code that has dependencies (described by an interface) while keeping the mock code inside the test it belongs to.

You write a struct full of function fields that mirror the interface, and matching methods that just call those fields.

This allows you to write test code like this:

func TestCompleteSignup(t *testing.T) {

var sentTo string
    // use the mocked object
mockedEmailSender = &EmailSenderMock{
SendFunc: func(to, subject, body string) error {
sentTo = to
return nil
},
}

CompleteSignUp("
[email protected]
", mockedEmailSender)

if len(mockedEmailSender.SendCalls()) != 1 {
t.Error("one Sender.Send expected")
}
if sentTo != "[email protected]" {
t.Errorf("unexpected recipient: %s", sentTo)
}

}

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

You mock out the functions in EmailSenderMock that you expect to be called, and you can write throwaway custom behaviour for each specific test. You can see that the mocked functions are inside the test function itself, so it’s very clear to see what interactions with EmailSender we’re expecting when we call the CompleteSignUp method.

Inside the mocked functions, you can make assertions about what methods are being called, as well as decisions about what values to return. For example, you can decide to return an error, and make sure the code you are testing handles it properly.

The trouble with this technique is that there is a lot of boilerplate code to write each time you want to mock an interface. That’s where Moq comes in…

Introducing moq

Moq is a simple tool that writes these structs for you. You can visit the project homepage at github.com/matryer/moq.

How it works

Add the go:generate comment above your interface:

package storage
//go:generate moq -out store_test.go . Store
type Store interface {
Get(id string) (interface{}, error)
Put(id string, v interface{}) error
}
  • The -out flag indicates where the output should be saved to
  • The dot (.) indicates that the interface lives in the current package
  • Store indicates that we want to mock the Store interface

Then run go generate in a terminal and Moq will generate a new file called store_test.go containing something like this:

package storage
type StoreMock struct {
// GetFunc mocks the Get function.
GetFunc func(id string) (interface{}, error)
    // PutFunc mocks the Put function.
PutFunc func(id string, v interface{}) error
}
// Get calls GetFunc.
func (mock *StoreMock) Get(id string) (interface{}, error) {
return mock.GetFunc(id)
}
// Put calls PutFunc.
func (mock *StoreMock) Put(id string, v interface{}) error {
return mock.PutFunc(id, v)
}
This code is simplified — the actual generated code is slightly more sophisticated.

You can then use StoreMock instances in your test code wherever you test code that relies on a Store.

You can install Moq and use it today with:

go get github.com/matryer/moq

As usual, feedback and questions are welcome on Twitter @matryer.

相關推薦

Meet Moq: Easily mock interfaces in Go

Meet Moq: Easily mock interfaces in GoMoq is an Interface mocking tool for go generate — github.com/matryer/moqIn my recent talk about Idiomatic Go Tricks

Yet another tool to mock interfaces in Go

Yet another tool to mock interfaces in Go https://itnext.io/yet-another-tool-to-mock-interfaces-in-go-73de1b02c041 As a powerful tool, uni

A GIF decoder: an exercise in Go interfaces

25 May 2011 Introduction At the Google I/O conference in San Francisco on May 10, 2011, we announced that the Go

理解golang反射(reflection in Go)

golang reflect golang反射 go反射機制 反射(reflection)是指在運行時,動態獲取程序結構信息(元信息)的一種能力,是靜態類型語言都支持的一種特性,如Java, golang等。這裏主要詳細介紹golang reflection相關知識類型與接口(Types and

Context propagation over HTTP in Go

https://medium.com/@rakyll/context-propagation-over-http-in-go-d4540996e9b0 Context propagation over HTTP in Go Go 1.7 introduced a built-in

Downloading large files in Go

package main import ( "fmt" "github.com/cavaliercoder/grab" "time" ) func download(dst string,urls ...string) { n:=len(urls) re,err:=grab.Get

How I organize my applications in Go[轉]

Overview For me, the hardest part of learning Go was in structuring my application. Prior to Go, I was working on a Rails applicat

Building an Excellent Mock Server in Swift using Vapor

What is a Mock Server?Before explaining what a mock server is, we’ll start with what a mock is and why you might use one. I’ll also avoid delving into the

Variadic function in Go

What is a variadic function?As we have seen in a functions lesson, a function is a piece of code dedicated to do a particular job. A function takes one or

How big is an int in Go?

How big is an int in Go?Go has several built-in numeric types, “sets of integer or floating-point values.” Some architecture-independent types are uint8 (8

5 advanced testing techniques in Go · Segment Blog

Go has a robust built-in testing library.  If you write Go, you already know this.  In this post we will discuss a handful of strategies to level up your G

Using Parser Combinators in Go

Using Parser Combinators in GoLet’s parse in Golang!How would you write a parser for the following calculator grammar?Digit := "0" | "1" | "2" | "3" | "4"

This Blogpost Deploys Servers in Go, NodeJS, Ruby, Python, Java, PHP

This Blogpost Deploys Servers in Go, NodeJS, Ruby, Python, Java, PHPRunning the embeded Repl.it code in this post will live-deploy simple http servers for

Tinyterm: A silly terminal emulator written in Go

This post is about Tinyterm, a silly hack that I presented as a lightning talk at last month’s Sydney Go User group 1. You can find the original slide

Bit manipulation in Go

Bit manipulation is important to know when doing data compression, cryptography and optimization. Bitwise operations include AND, NOT, OR, XOR and bit s

String manipulation in Go

Basic Operations Get char array of a String greeting := "Comment allez-vous" greeingCharacterArr := []rune(greeting) Get a char at the specific i

Based User Interfaces · Applied Go

Console applications usually take some parameters at start, and maybe some more input through basic console I/O. And that’s ok in most cases, though som

Processing spreadsheet data in Go · Applied Go

This article is also available as a video on the Applied Go YouTube channel: It is the shortened version of a lecture in my upcoming minicourse “

Scheduling In Go

IntroductionThe design and behavior of the Go scheduler allows your multithreaded Go programs to be more efficient and performant. This is thanks to the me

Bounds Check Elimination In Go

IntroductionOne day I was talking to Damian Gryski in Slack about some performance improvements he made to his go-metro package. When I first looked at the