fake

package module
v0.3.7 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 10, 2024 License: MIT Imports: 19 Imported by: 0

README

Fake

Fake is a Go type-safe mocking generator. It automatically creates type-safe mocks for any public interface.

Features

  • Type-safe mock generation
  • Support for generics
  • Granular mock generation
  • Mock cache for ultra-fast mock regeneration
  • Function call configuration, with Repeatability and Optional calls
  • Automatic call assertion
  • Caching, only regenerate updated interfaces
  • Automatic cleanup of generated mocks from removed code

Installation

Go install

Make sure $GO_PATH/bin is in your $PATH

go install github.com/sonalys/fake/entrypoint/fake@latest

Release download

Visit the Release Page and download the correct binary for your architecture/os.

Docker

You can safely run fake from a docker container using

docker run --rm -u $(id -u):$(id -g) -v .:/code ghcr.io/sonalys/fake:latest /fake -input /code -output /code/mocks

Usage


Usage:

  fake -input PATH -output mocks -ignore tests

The flags are:

  FLAG          TYPE      DEFAULT   DESCRIPTION
  -input        []STRING  .         Folder to scan for interfaces, can be invoked multiple times
  -output       STRING    mocks     Output folder, it will follow a tree structure repeating the package path
  -ignore       []STRING            Folder to ignore, can be invoked multiple times
  -interface    []STRING            Usually used with go:generate for granular mock generation for specific interfaces
  -mockPackage  STRING    mocks     Used with -interface. Specify the package name of the generated mock

Examples

A very simple example would be:

type UserDB interface {
	Login(userID string) error
}

Will generate the following mock:

type UserDB interface {
	Login(userID string) error
}
type StubInterface struct {
	setupLogin      mockSetup.Mock[func(userID string) error]
}

func (s *StubInterface[T]) OnLogin(funcs ...func(userID string) error) Config
func (s *StubInterface[T]) Login(userID string) error
...

Granular generation with go generate:

//go:generate fake -interface Reader
type Reader interface {
	io.Reader
}
// or
//go:generate go run github.com/sonalys/fake/entrypoint/fake -interface Reader
type Reader interface {
	io.Reader
}

Example usage for tests


func Test_Stub(t *testing.T) {
  mock := mocks.NewUserDB(t) // Setup call expectations
  config := mock.OnLogin(func(userID string) error {
    require.NotEmpty(t, userID)
    return nil
  })
  // Here you can configure it with:
  config.Repeat(1) // Repeat 1 is default behavior.
  // or with .Maybe(), which won't fail tests it not called.
  config.Maybe()

  var userDB UserDB = mock
  userDB.Login("userID") // Will call the previous function.
}

Contributors

Any issues or improvements discussions are welcome! Feel free to contribute. Thank you for your collaboration!


Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func GenerateInterface added in v0.3.0

func GenerateInterface(c GenerateInterfaceConfig)

func ParseImports

func ParseImports(imports []*ast.ImportSpec) *map[string]*PackageInfo

func Run

func Run(inputs []string, output string, ignore []string, interfaces ...string)

Types

type GenerateInterfaceConfig added in v0.3.0

type GenerateInterfaceConfig struct {
	PackageName   string
	Inputs        []string
	InterfaceName string
	OutputFolder  string
}

type Generator

type Generator struct {
	FileSet         *token.FileSet
	MockPackageName string
	// contains filtered or unexported fields
}

Generator is the controller for the whole module, caching files and holding metadata.

func NewGenerator

func NewGenerator(pkgName, baseDir string) (*Generator, error)

NewGenerator will create a new mock generator for the specified module.

func (*Generator) GenerateFile added in v0.3.0

func (g *Generator) GenerateFile(input string, interfaceNames ...string) []byte

func (*Generator) ParseFile

func (g *Generator) ParseFile(input string) (*ParsedFile, error)

type PackageInfo

type PackageInfo struct {
	Ref   *ast.ImportSpec
	Alias string
	Name  string
	Path  string
}

func ParsePackageInfo

func ParsePackageInfo(importPath string) (*PackageInfo, bool)

ParsePackageInfo parses the specified package and returns its package name and import path.

type ParsedField

type ParsedField struct {
	Interface *ParsedInterface
	Ref       *ast.Field
	Name      string
	Type      string
}

type ParsedFile

type ParsedFile struct {
	Generator       *Generator
	Size            int
	Ref             *ast.File
	PkgPath         string
	PkgName         string
	Imports         map[string]*imports.ImportEntry
	OriginalImports map[string]*imports.ImportEntry
	ImportsPathMap  map[string]*imports.ImportEntry
	UsedImports     map[string]struct{}
	// contains filtered or unexported fields
}

func (*ParsedFile) FindInterfaceByName

func (f *ParsedFile) FindInterfaceByName(name string) *ParsedInterface

func (*ParsedFile) ListInterfaces

func (f *ParsedFile) ListInterfaces(names ...string) []*ParsedInterface

type ParsedInterface

type ParsedInterface struct {
	ParsedFile    *ParsedFile
	Type          *ast.TypeSpec
	Ref           *ast.InterfaceType
	Name          string
	GenericsTypes []string
	GenericsNames []string
	// TranslateGenericNames translates generic type names from any imported interfaces.
	// Example:
	//	type A[T any] interface{ B[T] }
	//	type B[J any] interface{ Method() J }
	// it should have method Method() T when implementing A mock.
	TranslateGenericNames []string
	// contains filtered or unexported fields
}

func (*ParsedInterface) ListFields

func (i *ParsedInterface) ListFields() []*ParsedField

func (*ParsedInterface) PrintAstField

func (f *ParsedInterface) PrintAstField(i int, field *ast.Field, printName bool) string

func (*ParsedInterface) PrintAstFields

func (f *ParsedInterface) PrintAstFields(implFile io.Writer, fields []*ast.Field, printName bool)

func (*ParsedInterface) PrintMethodHeader

func (f *ParsedInterface) PrintMethodHeader(file io.Writer, methodName string, field *ParsedField)

func (*ParsedInterface) WriteMethodParams

func (f *ParsedInterface) WriteMethodParams(implFile io.Writer, params []*ast.Field)

func (*ParsedInterface) WriteMethodResults

func (f *ParsedInterface) WriteMethodResults(implFile io.Writer, results []*ast.Field)

Directories

Path Synopsis
entrypoint
internal

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL