diff --git a/README.md b/README.md index bdf7347..f77faa5 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,9 @@ moq [flags] source-dir interface [interface2 [interface3 [...]]] package name (default will infer) -stub return zero values when no mock implementation is provided, do not panic + -skip-ensure + suppress mock implementation check, avoid import cycle if mocks generated outside of the tested package + Specifying an alias for the mock is also supported with the format 'interface:alias' Ex: moq -pkg different . MyInterface:MyMock ``` diff --git a/main.go b/main.go index d6a5c8e..25add32 100644 --- a/main.go +++ b/main.go @@ -17,11 +17,12 @@ import ( var version string type userFlags struct { - outFile string - pkgName string - formatter string - stubImpl bool - args []string + outFile string + pkgName string + formatter string + stubImpl bool + skipEnsure bool + args []string } func main() { @@ -31,6 +32,8 @@ func main() { flag.StringVar(&flags.formatter, "fmt", "", "go pretty-printer: gofmt, goimports or noop (default gofmt)") flag.BoolVar(&flags.stubImpl, "stub", false, "return zero values when no mock implementation is provided, do not panic") + flag.BoolVar(&flags.skipEnsure, "skip-ensure", false, + "suppress mock implementation check, avoid import cycle if mocks generated outside of the tested package") flag.Usage = func() { fmt.Println(`moq [flags] source-dir interface [interface2 [interface3 [...]]]`) @@ -62,10 +65,11 @@ func run(flags userFlags) error { srcDir, args := flags.args[0], flags.args[1:] m, err := moq.New(moq.Config{ - SrcDir: srcDir, - PkgName: flags.pkgName, - Formatter: flags.formatter, - StubImpl: flags.stubImpl, + SrcDir: srcDir, + PkgName: flags.pkgName, + Formatter: flags.formatter, + StubImpl: flags.stubImpl, + SkipEnsure: flags.skipEnsure, }) if err != nil { return err diff --git a/pkg/moq/moq.go b/pkg/moq/moq.go index 1725361..cc07fd1 100644 --- a/pkg/moq/moq.go +++ b/pkg/moq/moq.go @@ -19,12 +19,13 @@ import ( // Mocker can generate mock structs. type Mocker struct { - srcPkg *packages.Package - tmpl *template.Template - pkgName string - pkgPath string - fmter func(src []byte) ([]byte, error) - stubImpl bool + srcPkg *packages.Package + tmpl *template.Template + pkgName string + pkgPath string + fmter func(src []byte) ([]byte, error) + stubImpl bool + skipEnsure bool imports map[string]bool } @@ -32,10 +33,11 @@ type Mocker struct { // Config specifies details about how interfaces should be mocked. // SrcDir is the only field which needs be specified. type Config struct { - SrcDir string - PkgName string - Formatter string - StubImpl bool + SrcDir string + PkgName string + Formatter string + StubImpl bool + SkipEnsure bool } // New makes a new Mocker for the specified package directory. @@ -69,13 +71,14 @@ func New(conf Config) (*Mocker, error) { } return &Mocker{ - tmpl: tmpl, - srcPkg: srcPkg, - pkgName: pkgName, - pkgPath: pkgPath, - fmter: fmter, - stubImpl: conf.StubImpl, - imports: make(map[string]bool), + tmpl: tmpl, + srcPkg: srcPkg, + pkgName: pkgName, + pkgPath: pkgPath, + fmter: fmter, + stubImpl: conf.StubImpl, + skipEnsure: conf.SkipEnsure, + imports: make(map[string]bool), }, nil } @@ -114,6 +117,7 @@ func (m *Mocker) Mock(w io.Writer, names ...string) error { PackageName: m.pkgName, Imports: moqImports, StubImpl: m.stubImpl, + SkipEnsure: m.skipEnsure, } mocksMethods := false @@ -254,6 +258,7 @@ type doc struct { Objects []obj Imports []string StubImpl bool + SkipEnsure bool } type obj struct { diff --git a/pkg/moq/moq_test.go b/pkg/moq/moq_test.go index 65a0639..b3211e1 100644 --- a/pkg/moq/moq_test.go +++ b/pkg/moq/moq_test.go @@ -172,6 +172,33 @@ func TestMoqExplicitPackageWithStaticCheck(t *testing.T) { } } +func TestMoqSkipEnsure(t *testing.T) { + m, err := New(Config{SrcDir: "testpackages/example", PkgName: "different", SkipEnsure: true}) + if err != nil { + t.Fatalf("moq.New: %s", err) + } + var buf bytes.Buffer + err = m.Mock(&buf, "PersonStore") + if err != nil { + t.Errorf("m.Mock: %s", err) + } + s := buf.String() + // assertions of things that should be mentioned + var strs = []string{ + "package different", + "type PersonStoreMock struct", + "CreateFunc func(ctx context.Context, person *example.Person, confirm bool) error", + "GetFunc func(ctx context.Context, id string) (*example.Person, error)", + "func (mock *PersonStoreMock) Create(ctx context.Context, person *example.Person, confirm bool) error", + "func (mock *PersonStoreMock) Get(ctx context.Context, id string) (*example.Person, error)", + } + for _, str := range strs { + if !strings.Contains(s, str) { + t.Errorf("expected but missing: \"%s\"", str) + } + } +} + func TestNotCreatingEmptyDirWhenPkgIsGiven(t *testing.T) { m, err := New(Config{SrcDir: "testpackages/example", PkgName: "different"}) if err != nil { diff --git a/pkg/moq/template.go b/pkg/moq/template.go index 442bdf1..fae942e 100644 --- a/pkg/moq/template.go +++ b/pkg/moq/template.go @@ -11,6 +11,7 @@ var moqTemplate = `// Code generated by moq; DO NOT EDIT. package {{.PackageName}} {{- $sourcePackagePrefix := .SourcePackagePrefix}} {{- $stubImpl := .StubImpl}} +{{- $skipEnsure := .SkipEnsure}} import ( {{- range .Imports }} @@ -20,9 +21,11 @@ import ( {{ range $i, $obj := .Objects -}} +{{- if not $skipEnsure -}} // Ensure, that {{.MockName}} does implement {{$sourcePackagePrefix}}{{.InterfaceName}}. // If this is not the case, regenerate this file with moq. var _ {{$sourcePackagePrefix}}{{.InterfaceName}} = &{{.MockName}}{} +{{- end }} // {{.MockName}} is a mock implementation of {{$sourcePackagePrefix}}{{.InterfaceName}}. // diff --git a/pkg/moq/testpackages/gogenvendoring/user/user_moq_test.go b/pkg/moq/testpackages/gogenvendoring/user/user_moq_test.go index 0ca586f..a9440cf 100644 --- a/pkg/moq/testpackages/gogenvendoring/user/user_moq_test.go +++ b/pkg/moq/testpackages/gogenvendoring/user/user_moq_test.go @@ -8,10 +8,6 @@ import ( "sync" ) -var ( - lockServiceMockDoSomething sync.RWMutex -) - // Ensure, that ServiceMock does implement Service. // If this is not the case, regenerate this file with moq. var _ Service = &ServiceMock{} @@ -43,6 +39,7 @@ type ServiceMock struct { In1 somerepo.SomeType } } + lockDoSomething sync.RWMutex } // DoSomething calls DoSomethingFunc. @@ -55,9 +52,9 @@ func (mock *ServiceMock) DoSomething(in1 somerepo.SomeType) error { }{ In1: in1, } - lockServiceMockDoSomething.Lock() + mock.lockDoSomething.Lock() mock.calls.DoSomething = append(mock.calls.DoSomething, callInfo) - lockServiceMockDoSomething.Unlock() + mock.lockDoSomething.Unlock() return mock.DoSomethingFunc(in1) } @@ -70,8 +67,8 @@ func (mock *ServiceMock) DoSomethingCalls() []struct { var calls []struct { In1 somerepo.SomeType } - lockServiceMockDoSomething.RLock() + mock.lockDoSomething.RLock() calls = mock.calls.DoSomething - lockServiceMockDoSomething.RUnlock() + mock.lockDoSomething.RUnlock() return calls }