Documentation
¶
Overview ¶
Package testutil provides testing infrastructure for gokit components.
The testutil package extends gokit's component lifecycle pattern with testing-specific capabilities, enabling easy setup, teardown, and state management for test components.
Quick Start ¶
Basic usage with automatic cleanup:
func TestMyFeature(t *testing.T) {
testutil.T(t).Setup(myComponent)
// Component is automatically cleaned up when test ends
}
Manual cleanup:
cleanup, err := testutil.Setup(myComponent)
if err != nil {
t.Fatal(err)
}
defer cleanup()
Managing multiple components:
manager := testutil.NewManager(ctx) manager.Add(dbComponent) manager.Add(redisComponent) manager.StartAll() defer manager.Cleanup()
Architecture ¶
The TestComponent interface extends component.Component with three testing-specific methods:
- Reset(ctx): Restore component to initial state
- Snapshot(ctx): Capture current state
- Restore(ctx, snapshot): Restore to a captured state
This hybrid approach provides consistency with production code while adding testing capabilities needed for test isolation and state management.
Thread Safety ¶
All Manager operations are thread-safe. Individual TestComponent implementations should ensure thread-safety if used in concurrent tests.
See the README.md for comprehensive documentation and examples.
Example (CustomTestComponent) ¶
ExampleTestComponent demonstrates implementing a custom test component
package main
import (
"fmt"
"github.com/kbukum/gokit/component"
)
func main() {
// This example shows the interface that test components must implement
type MyTestComponent struct {
name string
started bool
}
// Component interface
_ = func(c *MyTestComponent) string { return c.name } // Name()
_ = func(c *MyTestComponent) error { c.started = true; return nil } // Start(ctx)
_ = func(c *MyTestComponent) error { c.started = false; return nil } // Stop(ctx)
_ = func(c *MyTestComponent) component.Health { return component.Health{} } // Health(ctx)
// TestComponent interface additions
_ = func(c *MyTestComponent) error { return nil }
_ = func(c *MyTestComponent) (interface{}, error) { return map[string]interface{}{}, nil }
_ = func(c *MyTestComponent) error { return nil }
fmt.Println("TestComponent interface implemented")
}
Output: TestComponent interface implemented
Index ¶
- func ResetComponent(component TestComponent) error
- func ResetComponentWithContext(ctx context.Context, component TestComponent) error
- func Teardown(component TestComponent) error
- func TeardownWithContext(ctx context.Context, component TestComponent) error
- type CleanupFunc
- type Manager
- type THelper
- type TestComponent
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ResetComponent ¶
func ResetComponent(component TestComponent) error
ResetComponent resets a test component to its initial state.
func ResetComponentWithContext ¶
func ResetComponentWithContext(ctx context.Context, component TestComponent) error
ResetComponentWithContext resets a test component with a custom context.
func Teardown ¶
func Teardown(component TestComponent) error
Teardown stops a test component. This is the inverse of Setup and is provided for symmetry.
func TeardownWithContext ¶
func TeardownWithContext(ctx context.Context, component TestComponent) error
TeardownWithContext stops a test component with a custom context.
Types ¶
type CleanupFunc ¶
type CleanupFunc func() error
CleanupFunc is a function that performs cleanup, typically stopping a component.
func Setup ¶
func Setup(component TestComponent) (CleanupFunc, error)
Setup starts a test component and returns a cleanup function. The cleanup function should be called (typically with defer) to stop the component.
Example:
cleanup, err := testutil.Setup(dbComponent)
if err != nil {
t.Fatal(err)
}
defer cleanup()
Example ¶
ExampleSetup demonstrates basic component setup and teardown
// Create a test component
comp := newMockComponent("my-service")
// Setup starts the component and returns cleanup function
cleanup, err := testutil.Setup(comp)
if err != nil {
panic(err)
}
defer cleanup()
// Use the component in your test
health := comp.Health(context.Background())
fmt.Println(health.Status)
Output: healthy
func SetupWithContext ¶
func SetupWithContext(ctx context.Context, component TestComponent) (CleanupFunc, error)
SetupWithContext starts a test component with a custom context and returns a cleanup function.
type Manager ¶
type Manager struct {
// contains filtered or unexported fields
}
Manager provides lifecycle management for multiple test components. It allows starting, stopping, and resetting multiple components together, making it easier to manage complex test setups.
Example ¶
ExampleManager demonstrates managing multiple components
ctx := context.Background()
// Create manager
manager := testutil.NewManager(ctx)
// Add multiple components
manager.Add(newMockComponent("database"))
manager.Add(newMockComponent("redis"))
manager.Add(newMockComponent("kafka"))
// Start all components
if err := manager.StartAll(); err != nil {
panic(err)
}
defer manager.Cleanup()
// Get specific component
db := manager.Get("database")
fmt.Println(db.Name())
Output: database
Example (ResetAll) ¶
ExampleManager_resetAll demonstrates resetting all components
ctx := context.Background()
manager := testutil.NewManager(ctx)
comp := newMockComponent("test-db")
manager.Add(comp)
// Start component
manager.StartAll()
// Use component...
// (modify state)
// Reset all components to initial state
if err := manager.ResetAll(); err != nil {
panic(err)
}
fmt.Println("Components reset successfully")
Output: Components reset successfully
func NewManager ¶
NewManager creates a new test component manager.
func (*Manager) Add ¶
func (m *Manager) Add(component TestComponent)
Add registers a test component with the manager.
func (*Manager) Cleanup ¶
Cleanup is an alias for StopAll, provided for convenience. This makes it easy to use with defer or testing.T.Cleanup().
func (*Manager) Components ¶
func (m *Manager) Components() []TestComponent
Components returns all registered components.
func (*Manager) Get ¶
func (m *Manager) Get(name string) TestComponent
Get retrieves a component by name. Returns nil if no component with the given name is found.
func (*Manager) ResetAll ¶
ResetAll resets all registered components to their initial state. If any component fails to reset, returns immediately with that error.
type THelper ¶
type THelper struct {
// contains filtered or unexported fields
}
THelper provides testing.T integration for easier test setup.
Example (Snapshot) ¶
ExampleTHelper_snapshot demonstrates state snapshot and restore
t := &testing.T{} // In real tests, this comes from the test function
comp := newMockComponent("stateful-service")
testutil.T(t).Setup(comp)
// Capture current state
snapshot := testutil.T(t).Snapshot(comp)
// ... modify component state ...
// Restore to previous state
testutil.T(t).Restore(comp, snapshot)
fmt.Println("State restored successfully")
Output: State restored successfully
func T ¶
T wraps a testing.T to provide helper methods. This integrates testutil with Go's testing package for automatic cleanup.
Example:
func TestMyFeature(t *testing.T) {
testutil.T(t).Setup(dbComponent)
// component is automatically cleaned up when test ends
}
Example ¶
ExampleT demonstrates automatic cleanup with testing.T
t := &testing.T{} // In real tests, this comes from the test function
// Setup with automatic cleanup
comp := newMockComponent("my-service")
testutil.T(t).Setup(comp)
// Component is started and will be automatically cleaned up when test ends
health := comp.Health(context.Background())
fmt.Println(health.Status)
Output: healthy
func (*THelper) Reset ¶
func (h *THelper) Reset(component TestComponent)
Reset resets a component to its initial state.
func (*THelper) Restore ¶
func (h *THelper) Restore(component TestComponent, snapshot interface{})
Restore restores a component to a previously captured state.
func (*THelper) Setup ¶
func (h *THelper) Setup(component TestComponent)
Setup starts a component and registers cleanup with testing.T. The component will be automatically stopped when the test ends.
func (*THelper) Snapshot ¶
func (h *THelper) Snapshot(component TestComponent) interface{}
Snapshot captures the current state of a component.
type TestComponent ¶
type TestComponent interface {
component.Component
// Reset restores the component to its initial state.
// This is typically used between test cases to ensure test isolation.
Reset(ctx context.Context) error
// Snapshot captures the current state of the component.
// The returned data can be passed to Restore() to return to this state.
Snapshot(ctx context.Context) (interface{}, error)
// Restore restores the component to a previously captured state.
// The snapshot parameter should be a value returned by Snapshot().
Restore(ctx context.Context, snapshot interface{}) error
}
TestComponent extends component.Component with testing-specific lifecycle methods. Test components can be used both as regular components in the component registry and as test helpers with additional Reset/Snapshot/Restore capabilities.