如何为从 stdin 读取的内容编写 go Test 函数?
How do I write a go Test function for something that reads from stdin?
我有类似这样的测试代码:
func TestRollback(t *testing.T) {
store := NewStore()
// do some stuff
err := store.Rollback()
// checks
}
问题是 store.Rollback() 提示从标准输入读取 y 或 n
当 运行 go test -v --run TestRollback
时如何将“y”发送到测试进程
以下可以暂时重定向stdin。
rd,wr,err := os.Pipe()
saved := os.Stdin
os.Stdin = rd
... Test code feeds wr ...
os.Stdin = saved
测试您的 Rollback
方法的困难在于硬编码它对单例的依赖性 os.Stdin
。
是可行的,但是因为它改变了包级变量,所以它不适合并行进行 运行 测试。
一个更好的选择(IMO)在于使用一个接口。在 Go 中,测试通常与接口押韵。在这里,因为 os.Stdin
满足 io.Reader
接口,您可以使用传递给工厂函数的 io.Reader
参数化 Store
类型:
type Store struct {
// other fields, omitted here
in io.Reader
}
func NewStore(in io.Reader) *Store {
store := Store {
// other fields, omitted here
in: in,
}
return &store
}
然后,在您的测试函数中,您可以使用满足 io.Reader
且易于配置的具体类型,例如 *strings.Reader
:
func TestRollback(t *testing.T) {
// arrange
in := strings.Reader("-- put contents of stdin here --")
store := NewStore(in)
// act
err := store.Rollback()
// assert
// ...
}
我有类似这样的测试代码:
func TestRollback(t *testing.T) {
store := NewStore()
// do some stuff
err := store.Rollback()
// checks
}
问题是 store.Rollback() 提示从标准输入读取 y 或 n
当 运行 go test -v --run TestRollback
以下可以暂时重定向stdin。
rd,wr,err := os.Pipe()
saved := os.Stdin
os.Stdin = rd
... Test code feeds wr ...
os.Stdin = saved
测试您的 Rollback
方法的困难在于硬编码它对单例的依赖性 os.Stdin
。
一个更好的选择(IMO)在于使用一个接口。在 Go 中,测试通常与接口押韵。在这里,因为 os.Stdin
满足 io.Reader
接口,您可以使用传递给工厂函数的 io.Reader
参数化 Store
类型:
type Store struct {
// other fields, omitted here
in io.Reader
}
func NewStore(in io.Reader) *Store {
store := Store {
// other fields, omitted here
in: in,
}
return &store
}
然后,在您的测试函数中,您可以使用满足 io.Reader
且易于配置的具体类型,例如 *strings.Reader
:
func TestRollback(t *testing.T) {
// arrange
in := strings.Reader("-- put contents of stdin here --")
store := NewStore(in)
// act
err := store.Rollback()
// assert
// ...
}