Merge pull request #59 from breml/static-interface-check

Add static interface implementation check
This commit is contained in:
Mat Ryer 2019-01-21 17:39:36 +00:00 committed by GitHub
commit bb199b05e0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 93 additions and 4 deletions

View File

@ -13,6 +13,10 @@ var (
lockPersonStoreMockGet sync.RWMutex lockPersonStoreMockGet sync.RWMutex
) )
// Ensure, that PersonStoreMock does implement PersonStore.
// If this is not the case, regenerate this file with moq.
var _ PersonStore = &PersonStoreMock{}
// PersonStoreMock is a mock implementation of PersonStore. // PersonStoreMock is a mock implementation of PersonStore.
// //
// func TestSomethingThatUsesPersonStore(t *testing.T) { // func TestSomethingThatUsesPersonStore(t *testing.T) {

View File

@ -13,6 +13,10 @@ var (
lockMyInterfaceMockTwo sync.RWMutex lockMyInterfaceMockTwo sync.RWMutex
) )
// Ensure, that MyInterfaceMock does implement MyInterface.
// If this is not the case, regenerate this file with moq.
var _ MyInterface = &MyInterfaceMock{}
// MyInterfaceMock is a mock implementation of MyInterface. // MyInterfaceMock is a mock implementation of MyInterface.
// //
// func TestSomethingThatUsesMyInterface(t *testing.T) { // func TestSomethingThatUsesMyInterface(t *testing.T) {

View File

@ -2,12 +2,12 @@ package main
import ( import (
"bytes" "bytes"
"errors"
"flag" "flag"
"fmt" "fmt"
"io" "io"
"io/ioutil" "io/ioutil"
"os" "os"
"errors"
"github.com/matryer/moq/pkg/moq" "github.com/matryer/moq/pkg/moq"
) )

View File

@ -172,6 +172,10 @@ func (m *Mocker) Mock(w io.Writer, name ...string) error {
doc.Imports = append(doc.Imports, stripVendorPath(pkgToImport)) doc.Imports = append(doc.Imports, stripVendorPath(pkgToImport))
} }
if tpkg.Name() != m.pkgName {
doc.SourcePackagePrefix = tpkg.Name() + "."
}
var buf bytes.Buffer var buf bytes.Buffer
err = m.tmpl.Execute(&buf, doc) err = m.tmpl.Execute(&buf, doc)
if err != nil { if err != nil {
@ -262,9 +266,10 @@ func pkgInfoFromPath(src string) (*loader.PackageInfo, error) {
} }
type doc struct { type doc struct {
PackageName string PackageName string
Objects []obj SourcePackagePrefix string
Imports []string Objects []obj
Imports []string
} }
type obj struct { type obj struct {

View File

@ -42,6 +42,40 @@ func TestMoq(t *testing.T) {
} }
} }
func TestMoqWithStaticCheck(t *testing.T) {
m, err := New("testpackages/example", "")
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 example",
"var _ PersonStore = &PersonStoreMock{}",
"type PersonStoreMock struct",
"CreateFunc func(ctx context.Context, person *Person, confirm bool) error",
"GetFunc func(ctx context.Context, id string) (*Person, error)",
"func (mock *PersonStoreMock) Create(ctx context.Context, person *Person, confirm bool) error",
"func (mock *PersonStoreMock) Get(ctx context.Context, id string) (*Person, error)",
"panic(\"PersonStoreMock.CreateFunc: method is nil but PersonStore.Create was just called\")",
"panic(\"PersonStoreMock.GetFunc: method is nil but PersonStore.Get was just called\")",
"lockPersonStoreMockGet.Lock()",
"mock.calls.Get = append(mock.calls.Get, callInfo)",
"lockPersonStoreMockGet.Unlock()",
"// ID is the id argument value",
}
for _, str := range strs {
if !strings.Contains(s, str) {
t.Errorf("expected but missing: \"%s\"", str)
}
}
}
func TestMoqExplicitPackage(t *testing.T) { func TestMoqExplicitPackage(t *testing.T) {
m, err := New("testpackages/example", "different") m, err := New("testpackages/example", "different")
if err != nil { if err != nil {
@ -69,6 +103,34 @@ func TestMoqExplicitPackage(t *testing.T) {
} }
} }
func TestMoqExplicitPackageWithStaticCheck(t *testing.T) {
m, err := New("testpackages/example", "different")
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",
"var _ example.PersonStore = &PersonStoreMock{}",
"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)
}
}
}
// TestVeradicArguments tests to ensure variadic work as // TestVeradicArguments tests to ensure variadic work as
// expected. // expected.
// see https://github.com/matryer/moq/issues/5 // see https://github.com/matryer/moq/issues/5

View File

@ -8,6 +8,7 @@ var moqTemplate = `// Code generated by moq; DO NOT EDIT.
// github.com/matryer/moq // github.com/matryer/moq
package {{.PackageName}} package {{.PackageName}}
{{- $sourcePackagePrefix := .SourcePackagePrefix}}
import ( import (
{{- range .Imports }} {{- range .Imports }}
@ -22,6 +23,10 @@ var (
{{- end }} {{- end }}
) )
// Ensure, that {{.InterfaceName}}Mock does implement {{.InterfaceName}}.
// If this is not the case, regenerate this file with moq.
var _ {{$sourcePackagePrefix}}{{.InterfaceName}} = &{{.InterfaceName}}Mock{}
// {{.InterfaceName}}Mock is a mock implementation of {{.InterfaceName}}. // {{.InterfaceName}}Mock is a mock implementation of {{.InterfaceName}}.
// //
// func TestSomethingThatUses{{.InterfaceName}}(t *testing.T) { // func TestSomethingThatUses{{.InterfaceName}}(t *testing.T) {

View File

@ -12,6 +12,10 @@ var (
lockServiceMockUser sync.RWMutex lockServiceMockUser sync.RWMutex
) )
// Ensure, that ServiceMock does implement Service.
// If this is not the case, regenerate this file with moq.
var _ dotimport.Service = &ServiceMock{}
// ServiceMock is a mock implementation of Service. // ServiceMock is a mock implementation of Service.
// //
// func TestSomethingThatUsesService(t *testing.T) { // func TestSomethingThatUsesService(t *testing.T) {

View File

@ -12,6 +12,10 @@ var (
lockServiceMockDoSomething sync.RWMutex lockServiceMockDoSomething sync.RWMutex
) )
// Ensure, that ServiceMock does implement Service.
// If this is not the case, regenerate this file with moq.
var _ Service = &ServiceMock{}
// ServiceMock is a mock implementation of Service. // ServiceMock is a mock implementation of Service.
// //
// func TestSomethingThatUsesService(t *testing.T) { // func TestSomethingThatUsesService(t *testing.T) {

View File

@ -1,3 +1,4 @@
package somerepo package somerepo
// SomeType is some type
type SomeType string type SomeType string