testkit

package
v0.1.1 Latest Latest
Warning

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

Go to latest
Published: Mar 12, 2026 License: MIT Imports: 4 Imported by: 2

Documentation

Overview

Package testkit provides utilities for testing setups including a modular builder framework.

The testkit library offers a comprehensive set of tools for creating consistent, maintainable test environments. It provides interfaces, ready-to-use structs, and patterns for creating reusable builders, fixtures, and mocks.

Core Components

The library is built around three main components:

1. Builder Interface and BaseBuilder: A flexible builder pattern implementation 2. BuilderFactory: Factory pattern for creating and managing different builder types 3. BuilderConfig: Configuration system for setting up builders with default values

Basic Usage

Creating a simple builder:

builder := NewBaseBuilder()
builder.WithTag("env", "test").WithValidation(true)
result := builder.Build() // Returns nil for base builder

Using the factory pattern:

factory := NewBuilderFactory()
factory.Register("mybuilder", func() Builder {
	return NewBaseBuilder()
})

builder, err := factory.Create("mybuilder")
if err != nil {
	// handle error
}

Creating Custom Builders

To create a custom builder, embed BaseBuilder and implement the Builder interface:

type MyObjectBuilder struct {
	*BaseBuilder
	obj *MyObject
}

func NewMyObjectBuilder() *MyObjectBuilder {
	return &MyObjectBuilder{
		BaseBuilder: NewBaseBuilder(),
		obj:         &MyObject{},
	}
}

func (b *MyObjectBuilder) WithName(name string) *MyObjectBuilder {
	if b.IsValidationEnabled() && name == "" {
		b.AddError(errors.New("name cannot be empty"))
		return b
	}
	b.obj.Name = name
	return b
}

func (b *MyObjectBuilder) Build() interface{} {
	if b.HasErrors() {
		return fmt.Errorf("validation errors: %v", b.GetErrors())
	}
	// Return a copy to avoid mutation
	return &MyObject{Name: b.obj.Name}
}

Configuration System

Use BuilderConfig for setting up builders with defaults:

config := NewBuilderConfig()
config.WithValidation(false)
config.WithTag("env", "test")
config.WithDefault("name", "default_name")

builder := NewMyObjectBuilder()
config.ApplyTo(builder)

Thread Safety

The builders in this library are not thread-safe by design. Each goroutine should use its own builder instance. Use Clone() to create independent copies when needed.

Error Handling

Builders accumulate errors during configuration and report them at build time:

builder := NewMyObjectBuilder()
builder.WithName("") // Adds validation error

result := builder.Build()
if err, ok := result.(error); ok {
	// Handle build errors
}

Index

Constants

This section is empty.

Variables

View Source
var DefaultFactory = NewBuilderFactory() //nolint:gochecknoglobals // intentional singleton for convenience API

DefaultFactory is a global factory instance for convenience.

Functions

func RegisterBuilder

func RegisterBuilder(name string, createFunc func() Builder) error

RegisterBuilder registers a builder in the default factory.

Types

type BaseBuilder

type BaseBuilder struct {
	// contains filtered or unexported fields
}

BaseBuilder provides common functionality for all builders. It implements the Builder interface and can be embedded in specific builders.

func NewBaseBuilder

func NewBaseBuilder() *BaseBuilder

NewBaseBuilder creates a new BaseBuilder instance with default settings.

func (*BaseBuilder) AddError

func (b *BaseBuilder) AddError(err error) *BaseBuilder

AddError adds an error to the builder's error collection.

func (*BaseBuilder) Build

func (b *BaseBuilder) Build() any

Build is a default implementation that returns nil. Specific builders should override this method.

func (*BaseBuilder) ClearErrors

func (b *BaseBuilder) ClearErrors() *BaseBuilder

ClearErrors removes all errors from the builder.

func (*BaseBuilder) Clone

func (b *BaseBuilder) Clone() Builder

Clone creates a deep copy of the BaseBuilder.

func (*BaseBuilder) GetErrors

func (b *BaseBuilder) GetErrors() []error

GetErrors returns all errors accumulated by the builder.

func (*BaseBuilder) GetTag

func (b *BaseBuilder) GetTag(key string) string

GetTag retrieves a metadata tag value by key. Returns empty string if the tag doesn't exist.

func (*BaseBuilder) HasErrors

func (b *BaseBuilder) HasErrors() bool

HasErrors returns true if the builder has any errors.

func (*BaseBuilder) HasTag

func (b *BaseBuilder) HasTag(key string) bool

HasTag checks if a metadata tag exists.

func (*BaseBuilder) IsValidationEnabled

func (b *BaseBuilder) IsValidationEnabled() bool

IsValidationEnabled returns whether validation is enabled for this builder.

func (*BaseBuilder) Reset

func (b *BaseBuilder) Reset() Builder

Reset clears the builder state, allowing it to be reused.

func (*BaseBuilder) WithTag

func (b *BaseBuilder) WithTag(key, value string) *BaseBuilder

WithTag adds a metadata tag to the builder. Tags can be used for identification, debugging, or conditional logic.

func (*BaseBuilder) WithValidation

func (b *BaseBuilder) WithValidation(enabled bool) *BaseBuilder

WithValidation enables or disables validation for this builder.

type Builder

type Builder interface {
	// Build performs the final construction step and returns the built object.
	// Implementations should return the appropriate type for their specific builder.
	Build() any

	// Reset clears the builder state, allowing it to be reused.
	Reset() Builder

	// Clone creates a deep copy of the builder with the same configuration.
	Clone() Builder
}

Builder defines the interface that all builders must implement. This provides a common contract for all test builders in the library.

func CreateBuilder

func CreateBuilder(name string) (Builder, error)

CreateBuilder creates a builder from the default factory.

type BuilderConfig

type BuilderConfig struct {
	ValidationEnabled bool
	Tags              map[string]string
	DefaultValues     map[string]any
}

BuilderConfig provides configuration options for builders.

func NewBuilderConfig

func NewBuilderConfig() *BuilderConfig

NewBuilderConfig creates a new BuilderConfig with default settings.

func (*BuilderConfig) ApplyTo

func (c *BuilderConfig) ApplyTo(builder Builder) error

ApplyTo applies the configuration to a builder.

func (*BuilderConfig) WithDefault

func (c *BuilderConfig) WithDefault(key string, value any) *BuilderConfig

WithDefault sets a default value for a field.

func (*BuilderConfig) WithTag

func (c *BuilderConfig) WithTag(key, value string) *BuilderConfig

WithTag adds a tag to the configuration.

func (*BuilderConfig) WithValidation

func (c *BuilderConfig) WithValidation(enabled bool) *BuilderConfig

WithValidation sets the validation enabled flag.

type BuilderFactory

type BuilderFactory struct {
	// contains filtered or unexported fields
}

BuilderFactory provides a way to register and create different types of builders.

func NewBuilderFactory

func NewBuilderFactory() *BuilderFactory

NewBuilderFactory creates a new BuilderFactory instance.

func (*BuilderFactory) Create

func (f *BuilderFactory) Create(name string) (Builder, error)

Create creates a new builder instance by name.

func (*BuilderFactory) GetRegisteredNames

func (f *BuilderFactory) GetRegisteredNames() []string

GetRegisteredNames returns all registered builder names.

func (*BuilderFactory) IsRegistered

func (f *BuilderFactory) IsRegistered(name string) bool

IsRegistered checks if a builder is registered with the given name.

func (*BuilderFactory) Register

func (f *BuilderFactory) Register(name string, createFunc func() Builder) error

Register registers a builder creation function with a given name.

type ConfigurableBuilder

type ConfigurableBuilder interface {
	Builder
	ApplyConfig(config *BuilderConfig) error
}

ConfigurableBuilder interface for builders that can accept configuration.

type TestUser

type TestUser struct {
	ID       int
	Name     string
	Email    string
	Age      int
	Active   bool
	Tags     map[string]string
	Metadata map[string]any
}

TestUser represents a test user entity for demonstration purposes.

type UserBuilder

type UserBuilder struct {
	*BaseBuilder
	// contains filtered or unexported fields
}

UserBuilder builds TestUser instances for testing. It embeds BaseBuilder to inherit common functionality.

func NewUserBuilder

func NewUserBuilder() *UserBuilder

NewUserBuilder creates a new UserBuilder instance.

func (*UserBuilder) ApplyConfig

func (b *UserBuilder) ApplyConfig(config *BuilderConfig) error

ApplyConfig implements ConfigurableBuilder interface.

func (*UserBuilder) Build

func (b *UserBuilder) Build() any

Build creates the TestUser instance. It performs final validation and returns the user or an error.

func (*UserBuilder) Clone

func (b *UserBuilder) Clone() Builder

Clone creates a deep copy of the UserBuilder.

func (*UserBuilder) Reset

func (b *UserBuilder) Reset() Builder

Reset clears the builder state for reuse.

func (*UserBuilder) WithActive

func (b *UserBuilder) WithActive(active bool) *UserBuilder

WithActive sets the user active status.

func (*UserBuilder) WithAge

func (b *UserBuilder) WithAge(age int) *UserBuilder

WithAge sets the user age.

func (*UserBuilder) WithEmail

func (b *UserBuilder) WithEmail(email string) *UserBuilder

WithEmail sets the user email.

func (*UserBuilder) WithID

func (b *UserBuilder) WithID(id int) *UserBuilder

WithID sets the user ID.

func (*UserBuilder) WithMetadata

func (b *UserBuilder) WithMetadata(key string, value any) *UserBuilder

WithMetadata adds metadata to the user.

func (*UserBuilder) WithName

func (b *UserBuilder) WithName(name string) *UserBuilder

WithName sets the user name.

func (*UserBuilder) WithUserTag

func (b *UserBuilder) WithUserTag(key, value string) *UserBuilder

WithUserTag adds a tag specific to the user entity.

Jump to

Keyboard shortcuts

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