Skip to content

🎭 Mock Interfaces

pkg/composerutils/mock provides interface-based mock implementations, the cornerstone of the project's testability. By defining interfaces like CommandExecutor, FileSystemHelper, DownloadHelper, RuntimeInfo, upper modules can replace real system calls in tests.

Interface and Implementation List

InterfaceDefault ImplementationMock ImplementationUsage
CommandExecutorDefaultCommandExecutorMockCommandExecutorExecute system commands
FileSystemHelperDefaultFileSystemHelperMockFileSystemHelperFile system operations
DownloadHelper(implemented by caller)MockDownloadHelperFile download
RuntimeInfoMockRuntimeRuntime environment (GOOS/GOARCH)

CommandExecutor

go
type CommandExecutor interface {
    Execute(name string, args ...string) ([]byte, error)
}
  • DefaultCommandExecutor executes real commands using exec.Command.
  • MockCommandExecutor returns preset results by "command+args" key.

MockCommandExecutor

go
func NewMockCommandExecutor() *MockCommandExecutor
func (e *MockCommandExecutor) SetCommandResult(name string, args []string, output []byte, err error)
func (e *MockCommandExecutor) Execute(name string, args ...string) ([]byte, error)
go
mock := NewMockCommandExecutor()
mock.SetCommandResult("composer", []string{"--version"}, []byte("Composer 2.7.0"), nil)

out, err := mock.Execute("composer", "--version")
fmt.Println(string(out)) // Composer 2.7.0

Unmatched commands error

Execute returns 未找到模拟命令结果: <key> (mock command result not found) when no preset result is found, ensuring tests won't accidentally send real commands.

FileSystemHelper

go
type FileSystemHelper interface {
    CreateFile(path string, content []byte, perm os.FileMode) error
    CheckWritePermission(path string) error
    EnsureDirectoryExists(path string) error
    RemoveFile(path string) error
}

MockFileSystemHelper implements each method via function fields, all default to returning nil, can be replaced as needed:

go
func NewMockFileSystemHelper() *MockFileSystemHelper

type MockFileSystemHelper struct {
    CreateFileFunc            func(path string, content []byte, perm os.FileMode) error
    CheckWritePermissionFunc  func(path string) error
    EnsureDirectoryExistsFunc func(path string) error
    RemoveFileFunc            func(path string) error
}
go
mockFS := NewMockFileSystemHelper()
mockFS.CheckWritePermissionFunc = func(path string) error {
    return errors.New("mock no permission")
}
_ = mockFS.CheckWritePermission("/root")

DownloadHelper

go
type DownloadHelper interface {
    DownloadFile(url string, target string, config interface{}) error
}

MockDownloadHelper also uses DownloadFileFunc field, defaults to success.

MockRuntime

Mocks runtime environment, used to test platform-specific logic without real OS switching.

go
type RuntimeInfo struct {
    GOOS   string
    GOARCH string
}

func NewMockRuntime() *MockRuntime
func (r *MockRuntime) SetOS(os string)
func (r *MockRuntime) GetOS() string
func (r *MockRuntime) SetArch(arch string)
func (r *MockRuntime) GetArch() string
go
rt := NewMockRuntime()
rt.SetOS("darwin")
rt.SetArch("arm64")
fmt.Println(rt.GetOS(), rt.GetArch()) // darwin arm64

Design Significance

Why interface + Mock

pkg/composer's 234 methods all execute local composer binary. Running real composer in tests would be extremely slow and environment-dependent. By injecting Mock via CommandExecutor interface, tests complete in milliseconds, 450+ cases all run isolated. This is the foundation of the project's "comprehensive testing".

Advanced

Released under the MIT License