是否有人对term.ReadPassword(int(os.Stdin.Fd()))包中的golang.org/x/crypto/ssh/terminal调用进行模拟输入(出于测试目的)的最佳方法有任何成功或任何想法?

我尝试创建一个临时文件(vs os.Stdin)并将诸如testing\ntesting\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)!因此,现在您的测试不仅可以确保代码正常运行,而且实际上可以帮助您做出良好的设计决策。

08-06 10:27