Go Interface Mocking Tool

Overview

Charlatan

Circle CI codecov.io BSD Go Report Card

Percolate's Go Interface Mocking Tool. Please read our introductory blog post.

Installation

go get github.com/percolate/charlatan

Usage

  charlatan [options] <interface> ...
  charlatan -h | --help

Options:

  -dir string
        input package directory [default: current package directory]
  -file value
        name of input file, may be repeated, ignored if -dir is present
  -output string
        output file path [default: ./charlatan.go]
  -package string
        output package name [default: "<current package>"]

If you would like the mock implementations to live in the same package as the interface definition then use the simplest invocation as a directive:

//go:generate charlatan Interface

or from the command line:

charlatan -file=path/to/file.go Interface

You can chose the output path using -output, which must include the name of the generated source file. Any intermediate directories in the path that don't exist will be created. The package used in the generated file's package directive can be set using -package.

Example

Given the following interface:

package example

//go:generate charlatan Service

type Service interface {
	Query(filter *QueryFilter) ([]*Thing, error)
	Fetch(id string) (*Thing, error)
}

Running go generate ... for the above package/file should produce the file charlatan.go:

package example

type QueryInvocation struct {
	Parameters struct {
		Filter *QueryFilter
	}
	Results struct {
		Ident1 []*Thing
		Ident2 error
	}
}

type FetchInvocation struct {
	Parameters struct {
		Id string
	}
	Results struct {
		Ident3 *Thing
		Ident4 error
	}
}

type FakeService struct {
	QueryHook func(*QueryFilter) ([]*Thing, error)
	FetchHook func(string) (*Thing, error)

	QueryCalls []*QueryInvocation
	FetchCalls []*FetchInvocation
}

func (f *FakeService) Query(filter *QueryFilter) (id1 []*Thing, id2 error) {
	invocation := new(QueryInvocation)
	invocation.Parameters.Filter = filter

	id1, id2 := f.QueryHook(filter)

	invocation.Results.Ident1 = id1
	invocation.Results.Ident2 = id2

	return
}

// other generated code elided ...

Now you can use this in your tests by injecting the FakeService implementation instead of the actual one. A FakeService can be used anywhere a Service interface is expected.

func TestUsingService(t *testing.T) {
	// expectedThings := ...
	// expectedCriteria := ...
	svc := &example.FakeService{
		QueryHook: func(filter *QueryFilter) ([]*Thing, error) {
			if filter.Criteria != expectedCriteria {
				t.Errorf("expected criteria value: %v, have: %v", filter.Criteria, expectedCriteria)
				return nil, errors.New("unexpected criteria")
			}
			return expectedThings, nil
		},
	}

	// use the `svc` instance in the code under test ...

	// assert state of FakeService ...
	svc.AssertQueryCalledOnce(t)
}

Create anonymous function implementations for only those interface methods that should be called in the code under test. This will force a panic if any unexpected calls are made to the mock implementation.

The generated code has godoc formatted comments explaining the use of the mock and its methods.

Issues
  • Type error in generated mock

    Type error in generated mock

    What did you do?

    type Call struct{}
    
    //go:generate charlatan -output ./mockCallsDAL.go CallsDAL
    type CallsDAL interface {
    	Get(id uint64) (call *Call, err error)
    }
    

    What did you expect to see?

    Expected generated valid go code or some error

    What did you see instead?

    In this case, in function "SetGetInvocation" it generates code with a type error.

    System details

    Package version v1.0.4 ( 4cd615c902291bc9bebdba8bad0759cf5dda12e1 )

    go version go1.10.1 linux/amd64
    GOARCH="amd64"
    GOBIN=""
    GOCACHE="/home/tomat/.cache/go-build"
    GOEXE=""
    GOHOSTARCH="amd64"
    GOHOSTOS="linux"
    GOOS="linux"
    GOPATH="/home/tomat/Projects/go"
    GORACE=""
    GOROOT="/usr/lib/go"
    GOTMPDIR=""
    GOTOOLDIR="/usr/lib/go/pkg/tool/linux_amd64"
    GCCGO="gccgo"
    CC="gcc"
    CXX="g++"
    CGO_ENABLED="1"
    CGO_CFLAGS="-g -O2"
    CGO_CPPFLAGS=""
    CGO_CXXFLAGS="-g -O2"
    CGO_FFLAGS="-g -O2"
    CGO_LDFLAGS="-g -O2"
    PKG_CONFIG="pkg-config"
    GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build652025093=/tmp/go-build -gno-record-gcc-switches"
    GOROOT/bin/go version: go version go1.10.1 linux/amd64
    GOROOT/bin/go tool compile -V: compile version go1.10.1
    uname -sr: Linux 4.14.34-1-MANJARO
    LSB Version:	n/a
    Distributor ID:	ManjaroLinux
    Description:	Manjaro Linux
    Release:	17.1.8
    Codename:	Hakoila
    /usr/lib/libc.so.6: GNU C Library (GNU libc) stable release version 2.26, by Roland McGrath et al.
    
    bug 
    opened by 8tomat8 2
  • Variable names conflicts it generated mocks

    Variable names conflicts it generated mocks

    What did you do?

    type Type struct{}
    
    //go:generate charlatan -output ./mockTypesDAL.go TypesDAL
    type TypesDAL interface {
    	Get(id uint64) (t *Type, err error)
    }
    

    What did you expect to see?

    Expected generated valid go code or some error

    What did you see instead?

    Generated functions "NewFake*" with name conflicts. I think it because of the first letter of struct name.

    System details

    Package version v1.0.4 ( 4cd615c902291bc9bebdba8bad0759cf5dda12e1 )

    go version go1.10.1 linux/amd64
    GOARCH="amd64"
    GOBIN=""
    GOCACHE="/home/tomat/.cache/go-build"
    GOEXE=""
    GOHOSTARCH="amd64"
    GOHOSTOS="linux"
    GOOS="linux"
    GOPATH="/home/tomat/Projects/go"
    GORACE=""
    GOROOT="/usr/lib/go"
    GOTMPDIR=""
    GOTOOLDIR="/usr/lib/go/pkg/tool/linux_amd64"
    GCCGO="gccgo"
    CC="gcc"
    CXX="g++"
    CGO_ENABLED="1"
    CGO_CFLAGS="-g -O2"
    CGO_CPPFLAGS=""
    CGO_CXXFLAGS="-g -O2"
    CGO_FFLAGS="-g -O2"
    CGO_LDFLAGS="-g -O2"
    PKG_CONFIG="pkg-config"
    GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build652025093=/tmp/go-build -gno-record-gcc-switches"
    GOROOT/bin/go version: go version go1.10.1 linux/amd64
    GOROOT/bin/go tool compile -V: compile version go1.10.1
    uname -sr: Linux 4.14.34-1-MANJARO
    LSB Version:	n/a
    Distributor ID:	ManjaroLinux
    Description:	Manjaro Linux
    Release:	17.1.8
    Codename:	Hakoila
    /usr/lib/libc.so.6: GNU C Library (GNU libc) stable release version 2.26, by Roland McGrath et al.
    
    bug 
    opened by 8tomat8 2
  • Generate Helpers to Automate Stub Usage

    Generate Helpers to Automate Stub Usage

    Two new helpers are now added to eligible methods:

    (*Fake{Interface}) Set{Method}Stub

    func (f *Fake{Interface}) Set{Method}Stub(...)
    

    Set{Method}Stub configures Fake{Interface}.{Method} to always return the given values

    (*Fake{Interface}) Set{Method}Invocation

    func (f *Fake{Interface}) Set{Method}Invocation(calls []*{Interface}{Method}Invocation, fallback func() (...))
    

    Set{Method}Invocation configures Fake{Interface}.{Method} to return the given results when called with the given parameters. If no match is found for an invocation the result(s) of the fallback function are returned.

    enhancement 
    opened by kevinbirch 0
  • Small Fixes

    Small Fixes

    • Add Reset() method to fakes
    • Reset symbol generator for each parsed method so that unnamed parameters will have nicer names
    • Print the absolute path to the generated file for easier reference
    opened by kevinbirch 0
  • Support Embedded Interfaces

    Support Embedded Interfaces

    This PR inlines methods from embedded interfaces into the generated Fake. It does this by resolving embeded field identifers from the model cache and prepending the nested methods in source order. This recursive expansion happens just before the template is rendered so that the definition of embedded interfaces can occur after the definition of the embedder. To resolve embedded intefaces not defined in the current package, all intefaces in all imported packages are also scanned.

    The -file flag has been removed because we always want to scan an entire package. This ensure that we can find all available interfaces that might be embedded.

    Support for map and function parameter types has also been added.

    enhancement 
    opened by kevinbirch 0
  • Method naming conflict with Field and FieldNot.

    Method naming conflict with Field and FieldNot.

    Similarly named methods can cause auto-generated method naming conflicts. Specifically if an interface has a naming such as:

    Field(string, interface{}) FieldNot(string, interface{})

    While charlatan does code generation for Field(), it generates FieldCalled() and FieldNotCalled().

    When charlatan attempts to generate methods for FieldNot(), it will generate FieldNotCalled() and draw a method definition naming conflict error, as there is already a FieldNotCalled() method defined by code generation for Field().

    bug 
    opened by alan-mcnaney 1
  • Imports Incompatible with Go 1.11 Module Support

    Imports Incompatible with Go 1.11 Module Support

    charlatan: cannot find package "gopkg.in/olivere/elastic.v5" in any of:
            /usr/local/Cellar/go/1.10.1/libexec/src/gopkg.in/olivere/elastic.v5 (from $GOROOT)
            /Users/tmh/go/src/gopkg.in/olivere/elastic.v5 (from $GOPATH)
    service.go:49: running "charlatan": exit status 1
    

    cc @alan-mcnaney

    related: https://github.com/go-swagger/go-swagger/issues/1681

    bug 
    opened by solumos 4
Releases(v1.0.5)
Owner
Percolate
Percolate
HTTP traffic mocking and testing made easy in Go ༼ʘ̚ل͜ʘ̚༽

gock Versatile HTTP mocking made easy in Go that works with any net/http based stdlib implementation. Heavily inspired by nock. There is also its Pyth

Tom 1.6k Jun 24, 2022
GoMock is a mocking framework for the Go programming language.

gomock GoMock is a mocking framework for the Go programming language. It integrates well with Go's built-in testing package, but can be used in other

Go 7.6k Jun 30, 2022
HTTP mocking for Golang

httpmock Easy mocking of http responses from external resources. Install Currently supports Go 1.7 - 1.15. v1 branch has to be used instead of master.

Jared Morse 1.4k Jun 23, 2022
HTTP mocking to test API services for chaos scenarios

GAOS HTTP mocking to test API services for chaos scenarios Gaos, can create and provide custom mock restful services via using your fully-customizable

Trendyol Open Source 209 May 24, 2022
A clipboard-based mocking framework for Go that gets out of your way.

A clipboard-based mocking framework for Go that gets out of your way. This tool has been built with inspiration lovingly taken from Moq, and fuelled b

Roger Guldbrandsen 40 Jun 13, 2022
Lightweight HTTP mocking in Go (aka golang)

httpmock This library builds on Go's built-in httptest library, adding a more mockable interface that can be used easily with other mocking tools like

null 77 Jun 27, 2022
Full-featured test framework for Go! Assertions, mocking, input testing, output capturing, and much more! 🍕

testza ?? Testza is like pizza for Go - you could life without it, but why should you? Get The Module | Documentation | Contributing | Code of Conduct

Marvin Wendt 389 Jun 18, 2022
A simple and expressive HTTP server mocking library for end-to-end tests in Go.

mockhttp A simple and expressive HTTP server mocking library for end-to-end tests in Go. Installation go get -d github.com/americanas-go/mockhttp Exa

Americanas Go 6 Dec 19, 2021
A tool that integrates SQL, HTTP,interface,Redis mock

Mockit 目标:将mock变得简单,让代码维护变得容易 分支介绍 main 主分支,覆盖了单元测试 light 轻分支,去除了单元测试,简化了依赖项,方便其他团队使用 常见Mock难点 不同中间件,mock库设计模式不一致,学习代价高,差异化明显 mock方案强依赖服务端,无法灵活解耦 单元测试

SHIHUO 14 Apr 19, 2022
go-wrk - a HTTP benchmarking tool based in spirit on the excellent wrk tool (https://github.com/wg/wrk)

go-wrk - an HTTP benchmarking tool go-wrk is a modern HTTP benchmarking tool capable of generating significant load when run on a single multi-core CP

Tal Sliwowicz 560 Jun 26, 2022
Fortio load testing library, command line tool, advanced echo server and web UI in go (golang). Allows to specify a set query-per-second load and record latency histograms and other useful stats.

Fortio Fortio (Φορτίο) started as, and is, Istio's load testing tool and now graduated to be its own project. Fortio is also used by, among others, Me

Fortio (Φορτίο) 2.6k Jun 24, 2022
A tool for generating self-contained, type-safe test doubles in go

counterfeiter When writing unit-tests for an object, it is often useful to have fake implementations of the object's collaborators. In go, such fake i

Max Brunsfeld 678 Jun 20, 2022
Lightweight service virtualization/API simulation tool for developers and testers

API simulations for development and testing Hoverfly is a lightweight, open source API simulation tool. Using Hoverfly, you can create realistic simul

null 1.9k Jun 25, 2022
Powerful mock generation tool for Go programming language

Summary Minimock generates mocks out of Go interface declarations. The main features of minimock are: It generates statically typed mocks and helpers.

Juno Inc. 455 Jun 15, 2022
A next-generation testing tool. Orion provides a powerful DSL to write and automate your acceptance tests

Orion is born to change the way we implement our acceptance tests. It takes advantage of HCL from Hashicorp t o provide a simple DSL to write the acceptance tests.

Wesovi Labs 42 Jun 18, 2022
Stress testing and benchmarking tool for the NEAR EVM

evm-bully --- stress testing and benchmarking tool for the NEAR EVM

Project Aurora 28 May 30, 2022
HTTP load testing tool and library. It's over 9000!

Vegeta Vegeta is a versatile HTTP load testing tool built out of a need to drill HTTP services with a constant request rate. It can be used both as a

Tomás Senart 19.8k Jun 27, 2022
Fast cross-platform HTTP benchmarking tool written in Go

bombardier bombardier is a HTTP(S) benchmarking tool. It is written in Go programming language and uses excellent fasthttp instead of Go's default htt

Максим Федосеев 3.6k Jun 30, 2022
Coverage testing tool for The Go Programming Language

gocov Coverage reporting tool for The Go Programming Language Installation go get github.com/axw/gocov/gocov Usage There are currently four gocov comm

Andrew Wilkins 767 Jun 17, 2022