### Install Counterfeiter Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/_autodocs/10-project-summary.md Use 'go get' to install the Counterfeiter tool. Ensure you specify the major version for installation. ```bash go get -tool github.com/maxbrunsfeld/counterfeiter/v6 ``` -------------------------------- ### Example Header File Content Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/_autodocs/05-configuration.md This is an example of a header file that can be used with Counterfeiter. It demonstrates how to add build tags, such as `// +build integration`, which will be prepended to the generated fake file. ```go // +build integration ``` -------------------------------- ### NewInvocation Usage Example Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/_autodocs/02-command-module.md Demonstrates how to use `NewInvocation` to create an `Invocation` object, including environment variable retrieval and error handling for empty arguments. ```go import ( "os" "github.com/maxbrunsfeld/counterfeiter/v6/command" ) func main() { file := os.Getenv("GOFILE") line := // parse GOLINE from environment args := []string{"counterfeiter", "-o", "fakes", "mypackage", "MyInterface"} inv, err := command.NewInvocation(file, line, args) if err != nil { // handle: empty args } } ``` -------------------------------- ### Install Counterfeiter to `$GOPATH/bin` Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/README.md Install counterfeiter globally to `$GOPATH/bin` using `go install`. This allows invoking the `counterfeiter` command directly from the shell, even outside of a Go module context. ```shell go install github.com/maxbrunsfeld/counterfeiter/v6 $ ~/go/bin/counterfeiter USAGE counterfeiter [-generate>] [-o ] [-p] [--fake-name ] [-header ] [] [-] ``` -------------------------------- ### Generated File with License Header Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/_autodocs/09-usage-examples.md This is an example of the resulting generated file when a license header is included. It shows the header, the generated code notice, and the package declaration. ```go // Copyright (c) 2024 My Company. All rights reserved. // SPDX-License-Identifier: Apache-2.0 // Code generated by counterfeiter. DO NOT EDIT. package mypackagefakes ``` -------------------------------- ### Generated Interface Example Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/_autodocs/07-generated-fake-structure.md Example of an interface generated by Counterfeiter for the 'os' package, including public functions. ```go type Os interface { Open(name string) (*File, error) // ... other public functions } ``` -------------------------------- ### Setup Batch Generation with //counterfeiter:generate Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/_autodocs/09-usage-examples.md For packages with multiple interfaces, use the `//counterfeiter:generate` directive on each interface and a single `//go:generate` directive to enable faster batch generation. ```go // mypackage/interfaces.go package mypackage //go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 -generate //counterfeiter:generate . Writer //counterfeiter:generate . Reader //counterfeiter:generate . Closer type Writer interface { ... } type Reader interface { ... } type Closer interface { ... } ``` -------------------------------- ### Generated Shim Example Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/_autodocs/07-generated-fake-structure.md Example of a shim implementation generated by Counterfeiter, which delegates calls to the original package functions. ```go type OsShim struct{} func (p *OsShim) Open(name string) (*File, error) { return os.Open(name) } ``` -------------------------------- ### Add Counterfeiter as a Tool Dependency Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/README.md Install counterfeiter as a tool dependency using `go get -tool`. This command ensures counterfeiter is available for use with `go generate`. ```shell go get -tool github.com/maxbrunsfeld/counterfeiter/v6 ``` -------------------------------- ### Setup go:generate for Fake Generation Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/_autodocs/09-usage-examples.md Add a `//go:generate` directive to your interface file to automatically generate the fake implementation when `go generate` is run. This integrates counterfeiter into the Go toolchain. ```go // mypackage/writer.go package mypackage //go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 . Writer type Writer interface { Write(data []byte) (int, error) Close() error } ``` -------------------------------- ### Invocation Example Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/_autodocs/02-command-module.md Illustrates the expected `Invocation` struct content based on a typical `go:generate` directive. ```go // From a file myinterface.go with: // //counterfeiter:generate . MyInterface // Detect would return: // Invocation{ // Args: []string{"counterfeiter", ".", "MyInterface"}, // File: "myinterface.go", // Line: 3, // } ``` -------------------------------- ### Generate Fake for an Interface with Go Generate Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/_autodocs/09-usage-examples.md This example shows how to use `go generate` with Counterfeiter to automatically create a fake implementation for an interface. The `//go:generate` directive and `counterfeiter:generate` comment are essential. ```go // osshim/os_test.go //go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 -generate //counterfeiter:generate . Os func TestWithFakeOs(t *testing.T) { fake := &osshimfakes.FakeOs{} fake.OpenReturns(nil, errors.New("not found")) // Test code that uses Os interface } ``` -------------------------------- ### Go Thread-Safe Fake Example Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/_autodocs/07-generated-fake-structure.md Demonstrates safe concurrent usage of a generated fake. Multiple goroutines can call methods and query invocation counts simultaneously without data races. ```go fake := &FakeMyInterface{} // Safe from multiple goroutines go fake.DoThings("arg1", 123) go fake.DoThings("arg2", 456) // Safe to query while calls are happening count := fake.DoThingsCallCount() ``` -------------------------------- ### Counterfeiter Command-Line Usage Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/_autodocs/README.md Examples of how to invoke the counterfeiter command-line tool for basic usage, with options, via go:generate, and in batch mode. ```bash # Basic usage counterfeiter ./package InterfaceName ``` ```bash # With options counterfeiter -o ./fakes --fake-name CustomName ./package InterfaceName ``` ```bash # Via go:generate go generate ./... # processes //go:generate directives ``` ```bash # Batch mode (fastest) counterfeiter -generate # processes //counterfeiter:generate directives ``` -------------------------------- ### Slice Argument Handling Example Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/_autodocs/07-generated-fake-structure.md Demonstrates how Counterfeiter makes copies of slice arguments to detect caller modifications after the call. The recorded argument remains unchanged. ```go buffer := []byte{1} fake.ProcessBuffer(buffer) buffer[0] = 2 // Recorded argument is still {1} recorded := fake.ProcessBufferArgsForCall(0) // recorded[0] == 1 (copy was made) ``` -------------------------------- ### Batch Generation in CI/Build Pipelines Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/_autodocs/09-usage-examples.md This example shows how to use quiet mode (-q) within a loop to generate fakes for multiple packages in a CI or build pipeline. The `|| exit 1` ensures the script fails if any counterfeiter command fails. ```bash for pkg in $(find ./cmd -name "*.go" -exec dirname {} \; | sort | uniq); do counterfeiter -q "$pkg" MyInterface || exit 1 done ``` -------------------------------- ### Execute Batch Generation Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/_autodocs/09-usage-examples.md Running `go generate ./...` with the batch generation setup will process all `//counterfeiter:generate` directives in the package, significantly speeding up the fake generation process for multiple interfaces. ```bash go generate ./... # Much faster than separate //go:generate directives! ``` -------------------------------- ### Generated Interface for a Package Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/_autodocs/09-usage-examples.md This is an example of the Go interface generated by Counterfeiter for a package. It includes all exported functions and types from the target package. ```go // osshim/os.go (generated) type Os interface { Open(name string) (*File, error) ReadFile(name string) ([]byte, error) // ... all public functions from os package } ``` -------------------------------- ### Use go:generate with License Header Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/_autodocs/09-usage-examples.md Integrate license header generation into your build process using go:generate. This example shows how to use the counterfeiter command with the -header flag within a go:generate directive. ```go //go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 -header ./license.txt -generate //counterfeiter:generate . Writer ``` -------------------------------- ### Generated Fake API Usage Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/_autodocs/README.md Examples of interacting with a generated fake, including configuring behavior, stubbing methods, and querying call information. ```go fake := &mypackagefakes.FakeMyInterface{} // Configure behavior fake.DoThingsReturns(result, err) fake.DoThingsReturnsOnCall(0, result1, err1) fake.DoThingsStub = func(arg1 string) (int, error) { ... } // Use fake (implements MyInterface) result, err := fake.DoThings("test") // Query calls count := fake.DoThingsCallCount() arg1 := fake.DoThingsArgsForCall(0) all := fake.Invocations() ``` -------------------------------- ### Report Fake Generation Start Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/_autodocs/06-main-entry-point.md Prints a status message indicating which fake is being generated and its output path. Optionally adds a newline if the COUNTERFEITER_DEBUG environment variable is set. ```go func reportStarting(workingDir string, outputPath, fakeName string) error { relativePath, err := filepath.Rel(workingDir, outputPath) if err != nil { return fmt.Errorf("path resolution failed: %w", err) } fmt.Printf("Writing `%%s` to `%%s`...\n", fakeName, relativePath) if os.Getenv("COUNTERFEITER_DEBUG") != "" { fmt.Println() } return nil } ``` -------------------------------- ### Specify Custom Output File for Fake Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/_autodocs/09-usage-examples.md Use the -o flag with a file path to direct the generated fake to a specific file. This example places the FakeWriter struct into testhelpers/custom.go. ```bash counterfeiter -o ./testhelpers/custom.go ./mypackage Writer # Creates testhelpers/custom.go with FakeWriter struct ``` -------------------------------- ### Get First Non-Empty String Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/_autodocs/06-main-entry-point.md Returns the first non-empty string from a list of options. Useful for prioritizing configuration values, such as preferring a directive-specific header file over a global one. ```go func or(opts ...string) string ``` ```go a.HeaderFile = or(a.HeaderFile, args.HeaderFile) // Prefers directive-specific header, falls back to global header ``` -------------------------------- ### Specify Custom Output Directory for Fake Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/_autodocs/09-usage-examples.md Use the -o flag with a directory path to place the generated fake into a specific directory. Counterfeiter will auto-generate the filename within this directory. This example places the fake into ./testhelpers. ```bash counterfeiter -o ./testhelpers ./mypackage Writer # Creates testhelpers/fake_writer.go (filename auto-generated) ``` -------------------------------- ### Generate Fake using Fully-Qualified Name Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/_autodocs/09-usage-examples.md When generating fakes for standard library interfaces or interfaces without a clear package context in the command line, use their fully-qualified name. This example generates a fake for io.Writer. ```bash counterfeiter io.Writer # Creates iofakes/fake_writer.go ``` -------------------------------- ### Code Generation Orchestration Function Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/_autodocs/06-main-entry-point.md The `run` function orchestrates the entire code generation process. It handles profile initialization, logging setup, working directory detection, cache configuration, argument parsing, warning emissions for batch generation, invocation detection, and the generation loop for creating fake interfaces. It returns an error on any failure during the process. ```go func run() error ``` -------------------------------- ### Integrate with testify/assert Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/_autodocs/09-usage-examples.md Shows how to use a Counterfeiter-generated fake with the testify/assert package for testing. It covers setting return values and verifying method calls and their arguments. ```go import "github.com/stretchr/testify/assert" func TestWithTestify(t *testing.T) { fake := &mypackagefakes.FakeWriter{} fake.WriteReturns(5, nil) n, _ := fake.Write([]byte("test")) assert.Equal(t, 5, n) assert.Equal(t, 1, fake.WriteCallCount()) assert.Equal(t, []byte("test"), fake.WriteArgsForCall(0)) } ``` -------------------------------- ### Display Help with -help Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/_autodocs/05-configuration.md Show usage information and exit by using the -help flag. This is a standard flag for displaying command-line tool help. ```bash counterfeiter -help # Prints the usage message ``` -------------------------------- ### Main Entry Point Function Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/_autodocs/06-main-entry-point.md The `main` function is the executable's entry point. It disables garbage collection for performance, calls the `run` function to handle generation logic, and manages error reporting by printing messages and exiting with a non-zero status code upon failure. ```go func main() ``` -------------------------------- ### FileReader Interface Definition Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/_autodocs/04-types.md Defines the interface for reading file content. It provides a Get method to retrieve file content by path. ```go type FileReader interface { Get(cwd, path string) (content string, err error) } ``` -------------------------------- ### New Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/_autodocs/01-arguments-module.md Parses command-line arguments and returns structured configuration. It takes arguments, working directory, an evaler function, and a stater function as input. ```APIDOC ## Function: `New` Parses command-line arguments and returns structured configuration. ```go func New(args []string, workingDir string, evaler Evaler, stater Stater) (*ParsedArguments, error) ``` ### Parameters | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | args | []string | Yes | — | Command-line arguments, with index 0 being the program name | | workingDir | string | Yes | — | Absolute path to the current working directory | | evaler | Evaler | Yes | — | Function that evaluates symlinks/paths; typically `filepath.EvalSymlinks` | | stater | Stater | Yes | — | Function that stat files; typically `os.Stat` | ### Returns `*ParsedArguments` on success, `error` on validation failure. ### Error Cases - `"argument parsing requires at least one argument"` — args slice was empty - `usage` constant — help flag (`-help`) was provided - `"No such file/directory/package [path]"` — source path doesn't exist or can't be evaluated - Package/interface lookup errors during `parseSourcePackageDir` ### Example ```go import ( "path/filepath" "os" "github.com/maxbrunsfeld/counterfeiter/v6/arguments" ) func main() { cwd, _ := os.Getwd() args := []string{"counterfeiter", "-o", "fakes", "mypackage", "MyInterface"} parsed, err := arguments.New(args, cwd, filepath.EvalSymlinks, os.Stat) if err != nil { // handle error: invalid arguments } // parsed.InterfaceName == "MyInterface" // parsed.FakeImplName == "FakeMyInterface" // parsed.PackagePath == "mypackage" } ``` ``` -------------------------------- ### Fake EventBus with Channel Parameters Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/_autodocs/09-usage-examples.md Demonstrates creating a fake for an interface that takes a channel as a parameter and how to access the recorded channel. ```go type EventBus interface { Subscribe(topic string, ch chan Event) Unsubscribe(topic string, ch chan Event) } ``` ```go fake := &fakes.FakeEventBus{} ch := make(chan Event, 10) fake.Subscribe("topic", ch) // Channel is recorded like any other argument recorded := fake.SubscribeArgsForCall(0) // Can query about the channel ``` -------------------------------- ### Use Fake Generic Container with Type Specialization Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/_autodocs/09-usage-examples.md Example of using a generated fake for a generic interface after specializing it for a specific type (string). ```go func TestStringContainer(t *testing.T) { fake := &fakes.FakeContainer[string]{} fake.AddReturns(nil) fake.GetReturns("value", nil) // Use as Container[string] err := fake.Add("test") val, _ := fake.Get("key") } ``` -------------------------------- ### main Package Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/_autodocs/INDEX.md The entry point and core orchestration logic for the Counterfeiter tool. ```APIDOC ## `main` Package ### Functions - **`main()`** - Description: Entry point of the Counterfeiter application. - Signature: `func main()` - **`run()`** - Description: Orchestrates the fake generation process. - Signature: `func run()` - **`generate()`** - Description: Generates a single fake. - Signature: `func generate()` - **`doGenerate()`** - Description: Handles the code production for fake generation. - Signature: `func doGenerate()` - **`printCode()`** - Description: Handles the output of the generated code. - Signature: `func printCode(code string)` ``` -------------------------------- ### Generate Fake from External Package Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/_autodocs/09-usage-examples.md Counterfeiter can generate fakes for interfaces defined in external packages. This example generates a fake for the Pipeliner interface from the github.com/go-redis/redis package. ```bash counterfeiter github.com/go-redis/redis.Pipeliner # Creates pipeliner_fakes.go locally with FakePipeliner ``` -------------------------------- ### Integrate with Gomega Matchers Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/_autodocs/09-usage-examples.md Demonstrates how to use a Counterfeiter-generated fake with Gomega matchers for assertions in tests. It shows how to set return values and assert on call counts and arguments. ```go import . "github.com/onsi/gomega" func TestWithGomega(t *testing.T) { RegisterTestingT(t) fake := &mypackagefakes.FakeWriter{} fake.WriteReturns(5, nil) Expect(fake.WriteCallCount()).To(Equal(0)) fake.Write([]byte("test")) Expect(fake.WriteCallCount()).To(Equal(1)) Expect(fake.WriteArgsForCall(0)).To(Equal([]byte("test"))) } ``` -------------------------------- ### Get All Invocations on a Fake Object Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/_autodocs/09-usage-examples.md The `Invocations()` method returns a map of all method calls made to the fake object, including their arguments. This is useful for comprehensive assertion of behavior. ```go fake := &mypackagefakes.FakeWriter{} fake.Write([]byte("data")) fake.Close() fake.Write([]byte("more")) invocations := fake.Invocations() // invocations["Write"] == [][]interface{}{ // {[]byte("data")}, // {[]byte("more")}, // } // invocations["Close"] == [][]interface{}{ // {}, // } ``` -------------------------------- ### Format Method Parameters for Go Code Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/_autodocs/03-generator-module.md Demonstrates formatting parameter lists for different contexts in Go, such as function signatures or argument lists. ```go params := Params{ {Name: "arg1", Type: "string", IsVariadic: false, IsSlice: false}, {Name: "arg2", Type: "[]byte", IsVariadic: false, IsSlice: true}, } fmt.Println(params.AsNamedArgsWithTypes()) // "arg1 string, arg2Copy []byte" fmt.Println(params.AsArgs()) // "string, []byte" ``` -------------------------------- ### Construct a Fake with NewFake Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/_autodocs/03-generator-module.md Use `NewFake` to construct a fake by loading packages, finding the target interface or function, and extracting its signature. Ensure correct package paths and working directories are provided. ```go import ( "github.com/maxbrunsfeld/counterfeiter/v6/generator" ) func main() { cache := &generator.Cache{} fake, err := generator.NewFake( generator.InterfaceOrFunction, "MyInterface", "mypackage", "FakeMyInterface", "mypackagefakes", "", "/path/to/module", cache, ) if err != nil { // handle error: target not found, build errors, etc. } // fake.Methods now contains signatures of all methods in MyInterface } ``` -------------------------------- ### Get Arguments from Fake Method Calls Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/_autodocs/09-usage-examples.md Retrieve the arguments passed to a specific invocation of a fake method using `FakeMethodArgsForCall(index)`. This allows for detailed inspection of how methods were called. ```go fake := &mypackagefakes.FakeWriter{} fake.Write([]byte("hello")) fake.Write([]byte("world")) // Get arguments from first call (0-indexed) data := fake.WriteArgsForCall(0) if string(data) != "hello" { t.Errorf("Expected 'hello', got %q", string(data)) } // Get arguments from second call data = fake.WriteArgsForCall(1) if string(data) != "world" { t.Errorf("Expected 'world', got %q", string(data)) } ``` -------------------------------- ### Run `go generate` to Create Fake Implementations Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/README.md Execute the `go generate ./...` command to process all `go:generate` directives in your module, creating fake implementations for your interfaces. ```shell go generate ./... ``` -------------------------------- ### Fake Provider with Slice Return Values Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/_autodocs/09-usage-examples.md Shows how to generate a fake for an interface returning a slice and how to set the return values for its methods. ```go type Provider interface { GetItems(ctx context.Context, ids []string) ([]Item, error) } ``` ```go fake := &fakes.FakeProvider{} items := []Item{{ID: "1"}, {ID: "2"}} fake.GetItemsReturns(items, nil) result, _ := fake.GetItems(context.Background(), []string{"1", "2"}) // result == items ``` -------------------------------- ### Instantiate a Fake Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/README.md Import the generated fakes package and instantiate the fake struct for your interface. This fake can then be used to record interactions. ```go import "my-repo/path/to/foo/foofakes" var fake = &foofakes.FakeMySpecialInterface{} ``` -------------------------------- ### Generate Interface and Shim from Package Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/_autodocs/10-project-summary.md Use the `-p` flag to generate a Go interface and a shim implementation for all public functions within a specified package. This creates two files: one for the interface and one for the shim. ```bash counterfeiter -p os # Creates osshim/os.go (interface) and osshim/osshim.go (shim) ``` -------------------------------- ### Generate Fake with Custom Name Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/_autodocs/09-usage-examples.md Use the --fake-name flag to specify a custom struct name for the generated fake. This example creates a fake for the Writer interface in mypackage, naming the struct StubWriter. ```bash counterfeiter --fake-name StubWriter ./mypackage Writer # Creates mypackagefakes/stub_writer.go with struct StubWriter ``` -------------------------------- ### Record Arguments with Fake Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/README.md Call methods on the fake instance. The fake records the arguments passed to each call, allowing you to assert them later. ```go fake.DoThings("stuff", 5) Expect(fake.DoThingsCallCount()).To(Equal(1)) str, num := fake.DoThingsArgsForCall(0) Expect(str).To(Equal("stuff")) Expect(num).To(Equal(uint64(5))) ``` -------------------------------- ### Add License/Build Tag Headers Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/_autodocs/10-project-summary.md Include custom license information or build tags at the beginning of the generated file using the `-header` flag. Provide the path to a file containing the desired header content. ```bash counterfeiter -header ./header.txt ./package InterfaceName ``` -------------------------------- ### Fake Logger with Variadic Parameters Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/_autodocs/09-usage-examples.md Demonstrates creating a fake for an interface with variadic parameters and accessing the arguments passed to a method. ```go type Logger interface { Log(level string, args ...interface{}) } ``` ```go fake := &fakes.FakeLogger{} fake.Log("INFO", "message", 42, true) // Get arguments level, args := fake.LogArgsForCall(0) // level == "INFO" // args == []interface{}{"message", 42, true} ``` -------------------------------- ### Typical Test Pattern with Counterfeiter Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/_autodocs/10-project-summary.md Demonstrates the standard approach to using a Counterfeiter fake in Go tests. It shows how to create a fake, configure its behavior, run the code under test, and verify interactions. ```go import "mymodule/mypackagefakes" func TestMyLogic(t *testing.T) { // Create fake fake := &mypackagefakes.FakeService{} // Configure behavior fake.GetUserReturns(&User{ID: "1"}, nil) // Run code under test with fake result := MyLogicUnderTest(fake) // Verify behavior if fake.GetUserCallCount() != 1 { t.Errorf("GetUser should have been called once") } if result != expected { t.Errorf("Expected %v, got %v", expected, result) } } ``` -------------------------------- ### Fake ConfigManager with Map Parameters Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/_autodocs/09-usage-examples.md Illustrates generating a fake for an interface that accepts a map as a parameter and retrieving the passed map. ```go type ConfigManager interface { SetConfig(cfg map[string]string) error } ``` ```go fake := &fakes.FakeConfigManager{} fake.SetConfigReturns(nil) cfg := map[string]string{"key": "value"} fake.SetConfig(cfg) // Get the map that was passed passed := fake.SetConfigArgsForCall(0) // passed == cfg ``` -------------------------------- ### Format Return Signature Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/_autodocs/03-generator-module.md Demonstrates how to use the `AsReturnSignature` method to format a slice of `Return` structs into a comma-separated string representing the function's return types. This is useful for generating function signatures. ```go returns := Returns{ {Name: "result1", Type: "string"}, {Name: "result2", Type: "error"}, } fmt.Println(returns.AsReturnSignature()) // "(string, error)" ``` -------------------------------- ### Use Fake Interface in Tests Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/_autodocs/09-usage-examples.md In your tests, import the generated fake package and instantiate the fake. You can then configure its return values and assert on method call counts. ```go // mypackage/writer_test.go package mypackage import ( "github.com/myuser/mymodule/mypackage/mypackagefakes" testing ) func TestSomethingThatUsesWriter(t *testing.T) { fake := &mypackagefakes.FakeWriter{} // Configure return values fake.WriteReturns(5, nil) fake.CloseReturns(nil) // Call code that uses Writer result, _ := fake.Write([]byte("hello")) // Assert behavior if result != 5 { t.Errorf("expected 5, got %d", result) } if fake.WriteCallCount() != 1 { t.Errorf("Write should have been called once") } } ``` -------------------------------- ### Generate All Fakes with go:generate Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/_autodocs/09-usage-examples.md Run `go generate ./...` in your project root to automatically generate fakes for all interfaces with `//go:generate` directives. This command scans all Go files for such directives. ```bash go generate ./... # Scans all .go files for //go:generate directives with counterfeiter # Creates mypackagefakes/fake_writer.go ``` -------------------------------- ### Load Go Packages with Caching Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/_autodocs/08-internal-architecture.md Loads Go packages using `golang.org/x/tools/go/packages`, incorporating a cache check, import path resolution, and comprehensive error handling. It loads the main package, dependencies, and test packages. ```go func (f *Fake) loadPackages(c Cacher, workingDir string) error ``` -------------------------------- ### Generate Fake for Generic Interface Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/_autodocs/09-usage-examples.md Shows the command-line usage for generating a fake implementation of a generic Go interface. ```bash counterfeiter . Container # Creates FakeContainer[T any] ``` -------------------------------- ### or Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/_autodocs/06-main-entry-point.md Returns the first non-empty string from the provided arguments. This is useful for selecting a configuration value from multiple sources, prioritizing the first non-empty option. ```APIDOC ## Function: `or` Returns the first non-empty string from the arguments. ```go func or(opts ...string) string ``` ### Parameters #### Path Parameters - **opts** (...string) - Required - A variadic list of strings to check. ### Usage Used for: Selecting header file from global or local directive (whichever is specified) ### Example ```go a.HeaderFile = or(a.HeaderFile, args.HeaderFile) // Prefers directive-specific header, falls back to global header ``` ``` -------------------------------- ### Generate Mock via go:generate Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/_autodocs/10-project-summary.md Integrate mock generation directly into your Go project using `go:generate`. This command should be placed in a Go file and executed with `go generate`. ```go //go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 . InterfaceName ``` -------------------------------- ### Go: Generate Fake Implementation Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/_autodocs/06-main-entry-point.md Generates a single fake implementation, writing it to disk or stdout. It handles status reporting, code generation, formatting, and output. ```go func generate(workingDir string, args *ParsedArguments, cache generator.Cacher, headerReader generator.FileReader) error ``` -------------------------------- ### Enable Generate Mode with -generate Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/_autodocs/05-configuration.md Use the -generate flag to enable generate mode, which scans for `//counterfeiter:generate` directives in Go files. This allows for batch generation of multiple fakes. ```go //go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 -generate //counterfeiter:generate . MyInterface //counterfeiter:generate . MyOtherInterface //counterfeiter:generate . MyThirdInterface ``` ```bash go generate ./... # Runs counterfeiter -generate in the directory, which processes all # //counterfeiter:generate directives ``` -------------------------------- ### FromB Method Implementation Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/integration/testdata/expected_fake_multiab.txt Implements the FromB method for FakeMultiAB, handling stub calls, argument recording, and return value retrieval from package 'b'. It also records the invocation. ```go func (fake *FakeMultiAB) FromB() foob.S { fake.fromBMutex.Lock() ret, specificReturn := fake.fromBReturnsOnCall[len(fake.fromBArgsForCall)] fake.fromBArgsForCall = append(fake.fromBArgsForCall, struct{}{}) stub := fake.FromBStub fakeReturns := fake.fromBReturns fake.recordInvocation("FromB", []interface{}{}) fake.fromBMutex.Unlock() if stub != nil { return stub() } if specificReturn { return ret.result1 } return fakeReturns.result1 } ``` -------------------------------- ### Enable Counterfeiter CPU Profiling Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/_autodocs/05-configuration.md Set COUNTERFEITER_PROFILE to a non-empty value to enable CPU profiling. A CPU profile will be written to `./counterfeiter.profile` in the current directory, useful for performance analysis. ```bash COUNTERFEITER_PROFILE=1 counterfeiter ./mypackage MyInterface # Generates counterfeiter.profile in the current directory ``` -------------------------------- ### Standard `//go:generate` Directive Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/_autodocs/02-command-module.md Use this directive with the `go generate` command to generate a single mock. The Go toolchain automatically sets environment variables like GOFILE and GOLINE. ```go //go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 . MyInterface ``` -------------------------------- ### FromA Method Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/integration/testdata/expected_fake_multiab.txt The FromA method simulates the original FromA function from package 'a/foo'. It supports stubbing and return value configuration. ```APIDOC ## FromA Method ### Description Simulates the FromA function from package 'a/foo'. Allows for stubbing and setting return values. ### Method Signature `FromA() fooa.S` ### Usage This method can be called directly. You can track call counts, set stub functions, and configure return values for testing. #### Call Count `FromACallCount() int` - Returns the number of times FromA has been called. #### Stubbing `FromACalls(stub func() fooa.S)` - Sets a custom stub function for FromA. #### Return Values `FromAReturns(result1 fooa.S)` - Sets the default return value for FromA. `FromAReturnsOnCall(i int, result1 fooa.S)` - Sets a specific return value for the i-th call to FromA. ``` -------------------------------- ### FromA Method Implementation Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/integration/testdata/expected_fake_multiab.txt Implements the FromA method for FakeMultiAB, handling stub calls, argument recording, and return value retrieval from package 'a'. It also records the invocation. ```go func (fake *FakeMultiAB) FromA() fooa.S { fake.fromAMutex.Lock() ret, specificReturn := fake.fromAReturnsOnCall[len(fake.fromAArgsForCall)] fake.fromAArgsForCall = append(fake.fromAArgsForCall, struct{}{}) stub := fake.FromAStub fakeReturns := fake.fromAReturns fake.recordInvocation("FromA", []interface{}{}) fake.fromAMutex.Unlock() if stub != nil { return stub() } if specificReturn { return ret.result1 } return fakeReturns.result1 } ``` -------------------------------- ### FromB Method Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/integration/testdata/expected_fake_multiab.txt The FromB method simulates the original FromB function from package 'b/foo'. It provides options for stubbing and return value manipulation. ```APIDOC ## FromB Method ### Description Simulates the FromB function from package 'b/foo'. Allows for stubbing and setting return values. ### Method Signature `FromB() foob.S` ### Usage This method can be invoked directly. Features include tracking call counts, setting stub functions, and configuring return values for test cases. #### Call Count `FromBCallCount() int` - Returns the number of times FromB has been called. #### Stubbing `FromBCalls(stub func() foob.S)` - Assigns a custom stub function to FromB. #### Return Values `FromBReturns(result1 foob.S)` - Sets the default return value for FromB. `FromBReturnsOnCall(i int, result1 foob.S)` - Sets a specific return value for the i-th invocation of FromB. ``` -------------------------------- ### Generate Test Double for Third-Party Interface Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/README.md For interfaces in third-party packages, use the alternative syntax `.` with the `go tool counterfeiter` command. ```shell $ go tool counterfeiter github.com/go-redis/redis.Pipeliner ``` -------------------------------- ### Generate Mock for Interface Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/_autodocs/10-project-summary.md Use this command to generate a mock implementation for a specific interface within a Go package. Ensure the package path and interface name are correctly specified. ```bash counterfeiter ./package InterfaceName ``` -------------------------------- ### reportStarting Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/_autodocs/06-main-entry-point.md Prints a status message indicating which fake is being generated, including the fake name and its output path. Optionally adds a newline if COUNTERFEITER_DEBUG is set. ```APIDOC ## Function: `reportStarting` Prints a status message about which fake is being generated. ### Signature ```go func reportStarting(workingDir string, outputPath, fakeName string) error ``` ### Parameters #### Parameters - **workingDir** (string) - Required - Current working directory - **outputPath** (string) - Required - Absolute path where fake will be written - **fakeName** (string) - Required - Name of the generated fake struct ### Returns - error - Error if path resolution fails, nil on success ### Output Format ``` Writing `FakeName` to `relative/path/to/file.go`... ``` If `COUNTERFEITER_DEBUG` is set, a newline is added after the message. ``` -------------------------------- ### arguments Package Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/_autodocs/INDEX.md Provides functionality for parsing command-line arguments and managing configuration. ```APIDOC ## `arguments` Package ### Functions - **`New()`** - Description: CLI parsing function. - Signature: `func New() ParsedArguments` ### Types - **`ParsedArguments`** - Description: Configuration type for parsed arguments. ### Methods - **`PrettyPrint()`** - Description: Method to pretty print the parsed arguments. - Signature: `func (pa ParsedArguments) PrettyPrint() string` ### Interfaces - **`Evaler`** - Description: Interface for evaluation. - **`Stater`** - Description: Interface for state management. ``` -------------------------------- ### command Package Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/_autodocs/INDEX.md Handles task detection and command invocation. ```APIDOC ## `command` Package ### Functions - **`Detect()`** - Description: Detects tasks. - Signature: `func Detect() []string` - **`NewInvocation()`** - Description: Creates a new task invocation. - Signature: `func NewInvocation(command string, args []string) Invocation` ### Types - **`Invocation`** - Description: Represents a task invocation. ``` -------------------------------- ### Import Generated Fake Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/_autodocs/10-project-summary.md Import the package where Counterfeiter places the generated fake implementations. The package name typically includes 'fakes'. ```go import "mypkg/mypkgfakes" ``` -------------------------------- ### Batch Generate Interfaces with go:generate Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/_autodocs/10-project-summary.md For generating multiple fakes within a single package, use the -generate flag with go run and specify interfaces using the counterfeiter:generate directive. This is significantly faster than individual go:generate directives. ```go //go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 -generate //counterfeiter:generate . Interface1 //counterfeiter:generate . Interface2 ``` -------------------------------- ### Format and Print Go Code Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/_autodocs/06-main-entry-point.md Formats Go code using gofmt and writes it to a specified file path or standard output. Handles directory creation and file writing, returning errors on failure. ```go func printCode(code []byte, outputPath string, printToStdOut bool) error { formattedCode, err := format.Source(code) if err != nil { return fmt.Errorf("error from go/format.Source: %w", err) } if printToStdOut { _, err := os.Stdout.Write(formattedCode) if err != nil { return fmt.Errorf("Couldn't write to stdout - %v", err) } return nil } err = os.MkdirAll(filepath.Dir(outputPath), 0777) if err != nil { return fmt.Errorf("Couldn't create fake file - %v", err) } file, err := os.Create(outputPath) if err != nil { return fmt.Errorf("Couldn't create fake file - %v", err) } _, err = file.Write(formattedCode) if err != nil { return fmt.Errorf("Couldn't write to fake file - %v", err) } return file.Close() } ``` -------------------------------- ### Write Method Implementation Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/integration/testdata/expected_fake_writecloser.header.txt Implements the `Write` method for `FakeWriteCloser`. It records the arguments passed, handles stubbing, and manages return values, ensuring thread safety. ```go func (fake *FakeWriteCloser) Write(arg1 []byte) (int, error) { var arg1Copy []byte if arg1 != nil { arg1Copy = make([]byte, len(arg1)) copy(arg1Copy, arg1) } fake.writeMutex.Lock() ret, specificReturn := fake.writeReturnsOnCall[len(fake.writeArgsForCall)] fake.writeArgsForCall = append(fake.writeArgsForCall, struct { arg1 []byte }{arg1Copy}) stub := fake.WriteStub fakeReturns := fake.writeReturns fake.recordInvocation("Write", []interface{}{arg1Copy}) fake.writeMutex.Unlock() if stub != nil { return stub(arg1) } if specificReturn { return ret.result1, ret.result2 } return fakeReturns.result1, fakeReturns.result2 } ``` -------------------------------- ### Generate Shim for a Package Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/_autodocs/09-usage-examples.md Use the `counterfeiter -p ` command to generate an interface shim for a given Go package. This creates files for the interface and an implementation that delegates to the original package. ```bash counterfeiter -p os # Generates: # - osshim/os.go (interface with all exported os functions) # - osshim/osshim.go (implementation delegating to os package) ``` -------------------------------- ### generate Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/_autodocs/06-main-entry-point.md Generates a single fake implementation and writes it to disk or stdout. This is the main entry point for the counterfeiter CLI. ```APIDOC ## Function: `generate` Generates a single fake implementation and writes it to disk or stdout. ### Signature ```go func generate(workingDir string, args *ParsedArguments, cache generator.Cacher, headerReader generator.FileReader) error ``` ### Parameters - **workingDir** (string) - Absolute current working directory - **args** (*arguments.ParsedArguments) - Parsed command-line arguments - **cache** (generator.Cacher) - Cache for loaded packages - **headerReader** (generator.FileReader) - Reader for header files ### Returns Error on failure, nil on success ### Process 1. **Status reporting**: Unless `-q` flag is set, prints "Writing `FakeName` to `path/to/file.go`..." 2. **Code generation**: Calls `doGenerate()` to produce fake code 3. **Code formatting and output**: Calls `printCode()` to format and write output 4. **Success reporting**: Unless `-q` flag is set, prints "Done\n" ``` -------------------------------- ### Variadic Arguments Handling Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/_autodocs/07-generated-fake-structure.md Illustrates how variadic parameters are stored as slices in the generated fake's argument struct and how to access them. ```go type Logger interface { Log(level string, messages ...string) } ``` ```go logArgsForCall []struct { level string messages []string // variadic stored as slice } ``` ```go fake.Log("INFO", "message1", "message2") level, messages := fake.LogArgsForCall(0) // level == "INFO" // messages == []string{"message1", "message2"} ``` -------------------------------- ### Instantiate Generated Fake Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/_autodocs/10-project-summary.md Create an instance of the generated fake type. This allows you to use the fake implementation in your tests. ```go fake := &mypkgfakes.FakeMyInterface{} ``` -------------------------------- ### Parse Command-Line Arguments Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/_autodocs/01-arguments-module.md Use this function to parse command-line arguments and environment variables into a structured configuration object. It requires the arguments slice, current working directory, a path evaluation function, and a file stat function. Handles errors related to missing arguments, help flags, and invalid paths. ```go import ( "path/filepath" "os" "github.com/maxbrunsfeld/counterfeiter/v6/arguments" ) func main() { cwd, _ := os.Getwd() args := []string{"counterfeiter", "-o", "fakes", "mypackage", "MyInterface"} parsed, err := arguments.New(args, cwd, filepath.EvalSymlinks, os.Stat) if err != nil { // handle error: invalid arguments } // parsed.InterfaceName == "MyInterface" // parsed.FakeImplName == "FakeMyInterface" // parsed.PackagePath == "mypackage" } ``` -------------------------------- ### Return Fixed Values with Counterfeiter Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/_autodocs/09-usage-examples.md Use `Returns` to set a fixed value that the fake method will return on every call. This is useful for simple mocks where the behavior doesn't need to change. ```go fake := &mypackagefakes.FakeWriter{} fake.WriteReturns(10, nil) n, err := fake.Write([]byte("test")) // n == 10, err == nil (same for every call) ``` -------------------------------- ### FromBReturns Method Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/integration/testdata/expected_fake_multiab.txt Sets the default return values for the FromB method. This overrides any previously set stub or specific return values. ```go func (fake *FakeMultiAB) FromBReturns(result1 foob.S) { fake.fromBMutex.Lock() defer fake.fromBMutex.Unlock() fake.FromBStub = nil fake.fromBReturns = struct { result1 foob.S }{result1} } ``` -------------------------------- ### Generate Mocks in Batch Mode Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/_autodocs/10-project-summary.md Use `//counterfeiter:generate` directives in your code along with the `-generate` flag for efficient batch mock generation. This is useful for projects with many interfaces. ```go //counterfeiter:generate ``` -------------------------------- ### Format Import String Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/_autodocs/08-internal-architecture.md The `String` method formats an import for Go code. If the alias matches the package name, it returns the package path. Otherwise, it returns the alias followed by the package path in quotes. ```go func (i Import) String() string ``` ```go Import{Alias: "json", PkgPath: "encoding/json"}.String() // Output: "encoding/json" ``` ```go Import{Alias: "ej", PkgPath: "encoding/json"}.String() // Output: ej "encoding/json" ``` -------------------------------- ### FakeSomethingFactory Spy Method Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/integration/testdata/expected_fake_somethingfactory.txt The Spy method is the primary entry point for interacting with the fake. It records invocations, handles stubbed and specific return values, and allows for custom stubbing via the Stub field. ```go func (fake *FakeSomethingFactory) Spy(arg1 string, arg2 map[string]interface{}) string { fake.mutex.Lock() ret, specificReturn := fake.returnsOnCall[len(fake.argsForCall)] fake.argsForCall = append(fake.argsForCall, struct { arg1 string arg2 map[string]interface{} }{arg1, arg2}) stub := fake.Stub returns := fake.returns fake.recordInvocation("SomethingFactory", []interface{}{arg1, arg2}) fake.mutex.Unlock() if stub != nil { return stub(arg1, arg2) } if specificReturn { return ret.result1 } return returns.result1 } ``` -------------------------------- ### Generate Fake with License Header Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/_autodocs/09-usage-examples.md Include a license header in the generated fake by providing a path to a license file using the -header flag. This ensures compliance with licensing requirements. ```bash counterfeiter -header ./license.txt ./mypackage Writer ``` -------------------------------- ### Enable Package Mode with -p Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/_autodocs/05-configuration.md Activate package mode with the -p flag to generate an interface and shim for all public methods within a package. The first argument should be the package path. ```bash counterfeiter -p os # Generates: # - osshim/os.go (interface) # - osshim/osshim.go (shim implementation) ``` -------------------------------- ### Add or Retrieve Import Alias Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/_autodocs/03-generator-module.md Demonstrates how to use the `Add` method of the `Imports` struct to add a new import or retrieve the existing alias for a package. It ensures that the same package is not imported multiple times with different aliases. ```go imports := newImports() imp := imports.Add("json", "encoding/json") // imp.Alias == "json", imp.PkgPath == "encoding/json" // Importing same package again returns cached alias imp2 := imports.Add("encoding", "encoding/json") // imp2.Alias == "json" (same as before) ``` -------------------------------- ### Execute go generate Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/_autodocs/10-project-summary.md After adding the go:generate directive to your Go files, run this command to execute the generation process. ```bash go generate ./... ``` -------------------------------- ### Generate Interface with go:generate Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/_autodocs/10-project-summary.md Use this directive to generate a fake implementation for an interface using go:generate. Ensure the counterfeiter binary is accessible in your PATH or specify its full path. ```go package mypackage //go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 . MyInterface type MyInterface interface { DoThing(string) error } ``` -------------------------------- ### Generate Fake Interface Implementation Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/_autodocs/09-usage-examples.md Use the counterfeiter CLI command to generate a fake implementation of the defined interface. This command should be run from the package directory containing the interface. ```bash cd mypackage counterfeiter . Writer # Creates: mypackagefakes/fake_writer.go ``` -------------------------------- ### Generate Test Double with Counterfeiter Source: https://github.com/maxbrunsfeld/counterfeiter/blob/main/README.md Use the `go tool counterfeiter` command with the package path and interface name to generate a fake implementation. The output file path is indicated in the command's success message. ```shell $ go tool counterfeiter path/to/foo MySpecialInterface ```