Skip to content

Improve testability of ringctl cmd package

Problem

The cmd package in ringctl is currently hard to test due to:

  1. Inline RunE functions with business logic mixed with cobra command concerns
  2. Global client variable making dependency injection difficult
  3. Direct external dependencies in command handlers

Currently, the cmd package has no test files while lib/ and internal/ packages have excellent test coverage.

Proposed Solution

Refactor the cmd package to follow established Go CLI testing patterns:

Extract Command Logic

Move business logic from inline RunE functions to separate, testable functions:

// Current problematic approach
RunE: func(cmd *cobra.Command, args []string) error {
    ring, err := getRing(cmd)
    // ... business logic mixed with cobra concerns
}

// Better approach
RunE: func(cmd *cobra.Command, args []string) error {
    return runCellList(cmd, args, client) // thin wrapper
}

func runCellList(cmd *cobra.Command, args []string, client *tissue.Client) error {
    // testable business logic
}

Dependency Injection

Replace global client variable with dependency injection:

type CommandRunner struct {
    client *tissue.Client
    output io.Writer
}

func (r *CommandRunner) RunCellList(cmd *cobra.Command, args []string) error {
    // testable with mock client and output
}

Benefits

  • Improved test coverage for command execution logic
  • Easier debugging and maintenance
  • Consistent patterns with existing lib/ and internal/ packages
  • Mock-friendly architecture for unit testing

Files to Refactor

Files in cmd/.

Acceptance Criteria

  • Extract command logic into separate testable functions
  • Replace global client variable with dependency injection
  • Add unit tests for extracted command functions
  • Maintain existing CLI behavior and API
  • Follow patterns established in lib/ and internal/ packages
Edited by Reuben Pereira