メインコンテンツへスキップ
Golangで標準入力を使用する関数のテスト

Golangで標準入力を使用する関数のテスト

··3 分
Programming Golang
かずさプログラマー
著者
かずさプログラマー
業務の作業自動化を行っています。Go、VBA、Pythonを主に使用しています。過去にはC#、VB.Net、JavaScriptも使用していました。
目次

Golangの関数内で標準入力の値を受け取る関数に単体テストを行う方法をまとめました。

fmt.Scanで標準入力の値を受け取る関数
#

fmt.Scanを使用して標準入力から値を受け取る関数は、そのままだと単体テストができません。 下記のinputStdin関数は、関数内で標準入力の内容を受け取り、標準入力の内容をそのまま返す関数です。

func inputStdin() string {
	var inputValue string
	fmt.Println("入力してください")
	fmt.Print(">")
	fmt.Scan(&inputValue)
	return inputValue
}

inputStdinに単体テストを行うとエラーになります。

func TestInputStdin(t *testing.T) {
	got := inputStdin()
	want := "test"
	if got != want {
		t.Errorf("got %s, want %s", got, want)
	}
}
go test
入力してください
>--- FAIL: TestInputStdin (0.00s)
    main_test.go:12: got , want test

fmt.Scanの確認
#

fmt.Scanのコードを確認してみると、os.Stdinを第一引数に渡してFscanを呼び出しています。

func Scan(a ...any) (n int, err error) {
	return Fscan(os.Stdin, a...)
}

Fscanのコードを確認してみると、第一引数にio.Readerインターフェースの要件を満たす型を渡すことができます。引数rのio.Readerにos.Stdin以外の引数を渡すとテストできそうです。

func Fscan(r io.Reader, a ...any) (n int, err error) {
	s, old := newScanState(r, true, false)
	n, err = s.doScan(a)
	s.free(old)
	return
}

fmt.Fscanに書き換えて単体テスト
#

fmt.Scanだとos.Stdinから値を読み込んでしまうため、代わりにfmt.Fscanを使用し、 任意のio.Readerから値を取得できるようにします。

func inputStdin2(in io.Reader) string {

	if in == nil {
		in = os.Stdin
	}

	var inputValue string
	fmt.Println("入力してください")
	fmt.Print(">")
	fmt.Fscan(in, &inputValue)
	return inputValue
}
func inputStdin2(in io.Reader) string {

引数にio.Readerインターフェースの要件を満たすものを渡します。

	if in == nil {
		in = os.Stdin
	}

引数のinがnilのときはos.Stdinを入力に使用します。

fmt.Fscan(in, &inputValue)

fmt.Scanの代わりにfmt.Fscanを使用し、第一引数にinを渡します。
第二引数に値を書き込みたい変数を渡します。

inputStdin2に単体テストを行ってみます。

func TestInputStdin2(t *testing.T) {
	in := bytes.NewBufferString("test")
	got := inputStdin2(in)
	want := "test"
	if got != want {
		t.Errorf("got %s, want %s", got, want)
	}
}
in := bytes.NewBufferString("test")

bytes.NewBufferStringを利用してBuffer構造体を作成します。 Buffer構造体はio.Readerのインターフェース要件を満たしているため、inputStdin2の引数に渡すことができます。

テストを行うとokと表示されます。

go test
入力してください
>PASS
ok      stdin-unittest  0.223s

参考URL
#

関連記事

Robotgoでマウスポインタを自動で移動させる
·2 分
Programming Golang
Golangでライフゲームを作成しました
·1 分
Programming Golang
【Python】PyTorchとYOLOv5で物体の種類、座標、幅、高さを検出する
·3 分
Programming Python