2016-07-25 9 views
1

golang.org/x/crypto/ssh/terminalパッケージのterm.ReadPassword(int(os.Stdin.Fd()))コールにエントリを(テスト目的のために)偽装する最良の方法は何ですか?暗号化/ ssh/terminalを盗む

私は(os.Stdin対)の一時ファイルを作成し、一時ファイルにtesting\nまたはtesting\rのような文字列の値を書き込む試してみましたが、私はエラーinappropriate ioctl for deviceを取得します。私はそれが何かTTYに関連しているか、特定のフォーマットが見つからないと思っています(?)が、本当にわかりません。

ヘルプありがとうございます。

+0

どのような方法であなたは 'terminal.ReadPassword'をテストしようとしていますか?そのパッケージにテストを追加しようとしていますか?その関数は端末上でしか動かすことができないので、端末を持っていなければその関数を使わないでください。 – JimB

+0

私はその機能を使用するライブラリを作成しました。テストを作成しようとしましたが、ほとんどの場合、完全にカバーしていましたが、100%必要ではありませんでした。 私は通常の入力のための 'bufio.Reader'を使用していると私は、そのテストケースを処理するために、ファイルを変更することができますが、' terminal.ReadPassword'が同じように動作するようには思えません。あなただけの端末を持つことを条件ReadPasswordを使用して作成する必要があり – Luke

+0

https://github.com/goposse/tardy: ライブラリは、ここ(プラグを意味するものではない)あなたが提案を持っている場合です。あなたは、別の関数でラップコービンが提案したようPasswordReaderをからかっ、または単にIsTerminalをチェックするif文に別の条件を追加することによってそれを行うことができます。 – JimB

答えて

1

os.Stdinが参照している偽のファイルを作成してこのテストをスタブしている場合、ReadPassword()を処理しようとすると、テストは非常にOS固有のものになります。なぜなら、フードの下では、GoはOSに応じて別々のシステムコールをコンパイルしているからです。 ReadPassword()hereを実装しているが、アーキテクチャおよびOSに基づいて、システムコールはthis directoryです。あなたが見ることができるように、多くがあります。私はあなたが指定している方法でこのテストをスタブする良い方法を考えることができません。

問題の限られた理解し

私が提案するソリューションは、の線に沿ってシンプルなインターフェースを注入することです:あなたは、あなたのテストに偽のオブジェクトを渡すことができます

type PasswordReader interface { 
    ReadPassword(fd int) ([]byte, error) 
} 

func (pr PasswordReader) ReadPassword(fd int) ([]byte, error) { 
    return terminal.ReadPassword(fd) 
} 

この方法は、スタブReadPasswordへの応答です。私は、これはあなたのテストのためにコードを書くように感じて知っているが、terminalが注入されなければならない外部の依存関係(I/O)であるとして、あなたはこの考えをリフレームすることができます!だから、あなたのテストはコードの動作を保証するだけでなく、実際に優れた設計上の決定を下すのに役立ちます。

+0

これは実際には、コードのその部分も整理するのに役立ちます。提案していただきありがとうございます! – Luke