是否有人对term.ReadPassword(int(os.Stdin.Fd()))
包中的golang.org/x/crypto/ssh/terminal
调用进行模拟输入(出于测试目的)的最佳方法有任何成功或任何想法?
我尝试创建一个临时文件(vs os.Stdin
)并将诸如testing\n
或testing\r
的字符串值写入该临时文件,但出现错误inappropriate ioctl for device
。我猜这是TTY相关的东西或缺少的特定格式(?),但我确实不确定。
帮助表示赞赏。
最佳答案
如果通过创建os.Stdin
所引用的伪文件来对测试进行测试,则当您尝试处理ReadPassword()
时,测试将变得非常依赖于操作系统。这是因为Go会根据操作系统在编译单独的syscall。 ReadPassword()
是通过here实现的,但是基于体系结构和OS的系统调用在this directory中。如您所见,有很多。我想不出一种以您指定的方式存根此测试的好方法。
在对您的问题的了解有限的情况下,我建议的解决方案是按照以下方式注入(inject)一个简单的界面:
type PasswordReader interface {
ReadPassword(fd int) ([]byte, error)
}
func (pr PasswordReader) ReadPassword(fd int) ([]byte, error) {
return terminal.ReadPassword(fd)
}
这样,您可以将假对象传递给测试,并将响应存根到
ReadPassword
。我知道这就像为测试编写代码一样,但是您可以重新构造这种想法,因为terminal
是应该注入(inject)的外部依赖项(I/O)!因此,现在您的测试不仅可以确保代码正常运行,而且实际上可以帮助您做出良好的设计决策。