Skip to content

🎭 Mock 接口

pkg/composerutils/mock 提供接口化的 Mock 实现,是整个项目可测试性的基石。通过定义 CommandExecutorFileSystemHelperDownloadHelperRuntimeInfo 等接口,上层模块可在测试中替换真实系统调用。

接口与实现清单

接口默认实现Mock 实现用途
CommandExecutorDefaultCommandExecutorMockCommandExecutor执行系统命令
FileSystemHelperDefaultFileSystemHelperMockFileSystemHelper文件系统操作
DownloadHelper(由调用方实现)MockDownloadHelper文件下载
RuntimeInfoMockRuntime运行时环境(GOOS/GOARCH)

CommandExecutor

go
type CommandExecutor interface {
    Execute(name string, args ...string) ([]byte, error)
}
  • DefaultCommandExecutorexec.Command 执行真实命令。
  • MockCommandExecutor 按「命令+参数」键返回预设结果。

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

未匹配会报错

Execute 找不到预设结果时返回 未找到模拟命令结果: <key>,确保测试不会误发真实命令。

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 用函数字段实现每个方法,默认全部返回 nil,可按需替换:

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("模拟无权限")
}
_ = mockFS.CheckWritePermission("/root")

DownloadHelper

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

MockDownloadHelper 同样用 DownloadFileFunc 字段,默认成功。

MockRuntime

模拟运行时环境,用于测试平台相关逻辑而无需真实切换 OS。

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

设计意义

为什么用接口 + Mock

pkg/composer 的 234 个方法都执行本地 composer 二进制,测试时若真跑 composer 会极慢且依赖环境。通过 CommandExecutor 接口注入 Mock,测试可在毫秒级完成、450+ 用例全量隔离运行。这正是项目「测试完善」的基础。

进阶

基于 MIT 许可证发布