推荐用 os.CreateTemp 创建临时文件替代硬编码路径,defer 清理;用 bytes.Buffer 等模拟 io.Reader 避开磁盘 I/O;错误路径测试需 mock 标准错误;ioutil 已弃用,应改用 os.ReadFile/WriteFile 并验证文件权限。

用 os.CreateTemp 替代真实文件路径进行写入测试
硬编码测试路径(如 "./test.txt")会导致并发测试失败、权限问题或残留文件。Go 1.16+ 推荐用 os.CreateTemp 创建隔离的临时文件,测试完立刻 os.Remove 清理。
- 临时目录由系统管理,无需担心路径冲突
-
os.CreateTemp返回*os.File和完整路径,可直接传给待测函数 - 务必在
defer中调用os.Remove,否则多次运行后磁盘被占满 - 避免使用
ioutil.WriteFile等快捷函数做“黑盒”写入——它绕过你的业务逻辑,测不到打开/关闭/权限等真实行为
tmpFile, err := os.CreateTemp("", "test-*.txt")
if err != nil {
t.Fatal(err)
}
defer os.Remove(tmpFile.Name()) // 必须清理
defer tmpFile.Close()
// 把 tmpFile.Name() 传给你的 WriteToFile(path string) 函数
用 bytes.Buffer 或 io.NopCloser 模拟读取流,避开磁盘 I/O
如果你的函数接收 io.Reader(比如解析 CSV、JSON),不要读真实文件——它慢、不可控、难断言。优先注入内存流。
- 读字符串内容:用
bytes.NewBufferString("hello\nworld"),然后传给函数 - 读二进制数据:用
bytes.NewBuffer([]byte{0x01, 0x02}) - 若函数强制要求
io.ReadCloser(如某些 HTTP 客户端封装),用io.NopCloser(bytes.NewBufferString(...)) - 别用
ioutil.ReadFile在测试里读取 fixture 文件——它把测试变成集成测试,且 fixture 路径容易错
reader := io.NopCloser(bytes.NewBufferString(`{"name":"alice"}`))
data, err := ParseJSON(reader) // 你的函数
if err != nil {
t.Fatal(err)
}
if data.Name != "alice" {
t.Errorf("expected alice, got %s", data.Name)
}
测试错误路径时,故意让 os.Open 或 os.Stat 失败
真实场景中,文件不存在、无权限、是目录却当文件打开——这些错误必须覆盖。但不能靠“删掉某个文件再跑”,那不可靠也不幂等。
- 用
os.ErrNotExist、os.ErrPermission等标准错误构造 mock 行为 - 若函数内联调用了
os.Open,需将其抽成可注入的依赖(如func open(path string) (*os.File, error)),测试时替换为返回固定错误的闭包 - 不要用
os.Chmod("/tmp", 0000)去制造权限错误——它污染环境,且在 CI 中可能失败 - 检查错误是否包含预期信息(如
strings.Contains(err.Error(), "permission denied")),而不仅是err != nil
ioutil 已弃用,测试中请直接用 os + io 组合
Go 1.16 起 ioutil 包被移入 io 和 os,所有 ioutil.ReadFile、ioutil.WriteFile 都应替换。测试代码也得同步更新,否则会编译失败或隐式依赖旧版本。
立即学习“go语言免费学习笔记(深入)”;
-
ioutil.ReadFile→os.ReadFile(更轻量,不暴露*os.File) -
ioutil.WriteFile→os.WriteFile(同上,且默认 0644 权限,更安全) -
ioutil.TempDir→os.MkdirTemp - 注意:
os.ReadFile和os.WriteFile是原子操作,适合简单场景;但若要控制缓冲区大小、超时或进度回调,仍得用os.Open+io.Copy
// ✅ 正确(Go 1.16+)
content, err := os.ReadFile("config.json")
// ❌ 错误(已不存在)
// content, err := ioutil.ReadFile("config.json")
测试文件操作最易忽略的点:**没验证文件权限和所有权是否符合预期**。比如用 os.WriteFile 写出的文件默认是 0644,但某些场景需要 0600(如密钥文件)。别只断言内容,用 os.Stat 拿 Mode() 检查。










