testutils

package module
v0.3.0 Latest Latest
Warning

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

Go to latest
Published: Apr 10, 2025 License: MIT Imports: 8 Imported by: 0

README

testutils Build Status Go Report Card Coverage Status

Package testutils provides useful test helpers.

Details

Capture Utilities
  • CaptureStdout: Captures stdout output from the provided function
  • CaptureStderr: Captures stderr output from the provided function
  • CaptureStdoutAndStderr: Captures both stdout and stderr from the provided function

These capture utilities are useful for testing functions that write directly to stdout/stderr. They redirect the standard outputs to a buffer and return the captured content as a string.

Important Note: The capture functions are not thread-safe if used in parallel tests. For concurrent tests, it's better to pass a custom io.Writer to the function under test instead.

File Utilities
  • WriteTestFile: Creates a temporary file with specified content and returns its path. The file is automatically cleaned up after the test completes.
HTTP Test Utilities
  • MockHTTPServer: Creates a test HTTP server with the given handler. Returns the server URL and a cleanup function.
  • HTTPRequestCaptor: Returns a request captor and an HTTP handler that captures and records HTTP requests for later inspection.
Test Containers

The containers package provides several test containers for integration testing:

  • SSHTestContainer: SSH server container for testing SSH connections and operations
  • FTPTestContainer: FTP server container for testing FTP file transfers and operations
  • PostgresTestContainer: PostgreSQL database container with automatic database creation
  • MySQLTestContainer: MySQL database container with automatic database creation
  • MongoTestContainer: MongoDB container with support for multiple versions (5, 6, 7)
  • LocalstackTestContainer: LocalStack container with S3 service for AWS testing

Install and update

go get -u github.com/go-pkgz/testutils

Example Usage

Capture Functions
// Capture stdout
func TestMyFunction(t *testing.T) {
    output := testutils.CaptureStdout(t, func() {
        fmt.Println("Hello, World!")
    })
    
    assert.Equal(t, "Hello, World!\n", output)
}

// Capture stderr
func TestErrorOutput(t *testing.T) {
    errOutput := testutils.CaptureStderr(t, func() {
        fmt.Fprintln(os.Stderr, "Error message")
    })
    
    assert.Equal(t, "Error message\n", errOutput)
}

// Capture both stdout and stderr
func TestBothOutputs(t *testing.T) {
    stdout, stderr := testutils.CaptureStdoutAndStderr(t, func() {
        fmt.Println("Standard output")
        fmt.Fprintln(os.Stderr, "Error output")
    })
    
    assert.Equal(t, "Standard output\n", stdout)
    assert.Equal(t, "Error output\n", stderr)
}
File Utilities
// Create a temporary test file
func TestWithTempFile(t *testing.T) {
    content := "test file content"
    filePath := testutils.WriteTestFile(t, content)
    
    // Use the file in your test
    data, err := os.ReadFile(filePath)
    require.NoError(t, err)
    assert.Equal(t, content, string(data))
    
    // No need to clean up - it happens automatically when the test ends
}
HTTP Test Utilities
// Create a mock HTTP server
func TestWithMockServer(t *testing.T) {
    handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        w.WriteHeader(http.StatusOK)
        w.Write([]byte("response"))
    })
    
    serverURL, _ := testutils.MockHTTPServer(t, handler)
    
    // Make requests to the server
    resp, err := http.Get(serverURL + "/path")
    require.NoError(t, err)
    defer resp.Body.Close()
    
    assert.Equal(t, http.StatusOK, resp.StatusCode)
}

// Capture and inspect HTTP requests
func TestWithRequestCaptor(t *testing.T) {
    // Create a request captor
    captor, handler := testutils.HTTPRequestCaptor(t, nil)
    
    // Create a server with the capturing handler
    serverURL, _ := testutils.MockHTTPServer(t, handler)
    
    // Make a request
    http.Post(serverURL+"/api", "application/json", 
              strings.NewReader(`{"key":"value"}`))
    
    // Inspect the captured request
    req, _ := captor.GetRequest(0)
    assert.Equal(t, http.MethodPost, req.Method)
    assert.Equal(t, "/api", req.Path)
    assert.Equal(t, `{"key":"value"}`, string(req.Body))
}
Test Containers
// PostgreSQL test container
func TestWithPostgres(t *testing.T) {
    ctx := context.Background()
    pg := containers.NewPostgresTestContainer(ctx, t)
    defer pg.Close(ctx)
    
    db, err := sql.Open("postgres", pg.ConnectionString())
    require.NoError(t, err)
    defer db.Close()
    
    // run your tests with the database
}

// MySQL test container
func TestWithMySQL(t *testing.T) {
    ctx := context.Background()
    mysql := containers.NewMySQLTestContainer(ctx, t)
    defer mysql.Close(ctx)
    
    db, err := sql.Open("mysql", mysql.DSN())
    require.NoError(t, err)
    defer db.Close()
    
    // run your tests with the database
}

// MongoDB test container
func TestWithMongo(t *testing.T) {
    ctx := context.Background()
    mongo := containers.NewMongoTestContainer(ctx, t, 7) // version 7
    defer mongo.Close(ctx)
    
    coll := mongo.Collection("test_db")
    _, err := coll.InsertOne(ctx, bson.M{"test": "value"})
    require.NoError(t, err)
}

// SSH test container
func TestWithSSH(t *testing.T) {
    ctx := context.Background()
    ssh := containers.NewSSHTestContainer(ctx, t)
    defer ssh.Close(ctx)
    
    // use ssh.Address() to get host:port
    // default user is "test"
    sshAddr := ssh.Address()
}

// Localstack (S3) test container
func TestWithS3(t *testing.T) {
    ctx := context.Background()
    ls := containers.NewLocalstackTestContainer(ctx, t)
    defer ls.Close(ctx)
    
    s3Client, bucketName := ls.MakeS3Connection(ctx, t)
    
    // put object example
    _, err := s3Client.PutObject(ctx, &s3.PutObjectInput{
        Bucket: aws.String(bucketName),
        Key:    aws.String("test-key"),
        Body:   strings.NewReader("test content"),
    })
    require.NoError(t, err)
}

// FTP test container
func TestWithFTP(t *testing.T) {
    ctx := context.Background()
    ftpContainer := containers.NewFTPTestContainer(ctx, t)
    defer ftpContainer.Close(ctx)
    
    // Connection details
    ftpHost := ftpContainer.GetIP()        // Container host
    ftpPort := ftpContainer.GetPort()      // Container port (default: 2121)
    ftpUser := ftpContainer.GetUser()      // Default: "ftpuser"
    ftpPassword := ftpContainer.GetPassword() // Default: "ftppass"
    
    // Upload a file
    localFile := "/path/to/local/file.txt" 
    remotePath := "file.txt"
    err := ftpContainer.SaveFile(ctx, localFile, remotePath)
    require.NoError(t, err)
    
    // Download a file
    downloadPath := "/path/to/download/location.txt"
    err = ftpContainer.GetFile(ctx, remotePath, downloadPath)
    require.NoError(t, err)
    
    // List files
    entries, err := ftpContainer.ListFiles(ctx, "/")
    require.NoError(t, err)
    for _, entry := range entries {
        fmt.Println(entry.Name, entry.Type) // Type: 0 for file, 1 for directory
    }
}

Documentation

Overview

Package testutils provides utilities for testing Go applications

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CaptureStderr

func CaptureStderr(t *testing.T, f func()) string

CaptureStderr captures os.Stderr output from the provided function.

func CaptureStdout

func CaptureStdout(t *testing.T, f func()) string

CaptureStdout captures os.Stdout output from the provided function.

func CaptureStdoutAndStderr

func CaptureStdoutAndStderr(t *testing.T, f func()) (stdout, stderr string)

CaptureStdoutAndStderr captures os.Stdout and os.Stderr output from the provided function.

func MockHTTPServer added in v0.2.0

func MockHTTPServer(t *testing.T, handler http.Handler) (serverURL string, cleanup func())

MockHTTPServer creates a test HTTP server with the given handler. Returns the server URL and a function to close it.

func WriteTestFile added in v0.2.0

func WriteTestFile(t *testing.T, content string) string

WriteTestFile creates a temporary file with the given content and returns its path. The file is automatically cleaned up after the test completes.

Types

type RequestCaptor added in v0.2.0

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

RequestCaptor captures HTTP requests for inspection in tests

func HTTPRequestCaptor added in v0.2.0

func HTTPRequestCaptor(t *testing.T, next http.Handler) (*RequestCaptor, http.Handler)

HTTPRequestCaptor returns a request captor and HTTP handler that captures requests The returned handler will forward requests to the provided next handler if not nil

func (*RequestCaptor) GetRequest added in v0.2.0

func (c *RequestCaptor) GetRequest(idx int) (RequestRecord, bool)

GetRequest returns the request at the specified index

func (*RequestCaptor) GetRequests added in v0.2.0

func (c *RequestCaptor) GetRequests() []RequestRecord

GetRequests returns all captured requests

func (*RequestCaptor) Len added in v0.2.0

func (c *RequestCaptor) Len() int

Len returns the number of captured requests

func (*RequestCaptor) Reset added in v0.2.0

func (c *RequestCaptor) Reset()

Reset clears all captured requests

type RequestRecord added in v0.2.0

type RequestRecord struct {
	Method  string
	Path    string
	Headers http.Header
	Body    []byte
}

RequestRecord holds information about a captured HTTP request

Directories

Path Synopsis
Package containers implements various test containers for integration testing
Package containers implements various test containers for integration testing

Jump to

Keyboard shortcuts

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