Cobraを使ったGo CLIコマンドの出力をテストする方法

Cobra で作られた CLI アプリケーションで、サブコマンドが呼ばれたときに hello called という文字列が出力されたことをテストする例を紹介します。

hello サブコマンド

cobra-cli を使って、hello というサブコマンドを作成します。

$ cobra-cli init
$ cobra-cli add hello

$ go run main.go hello
hello called

cmd/hello.go

var helloCmd = &cobra.Command{
	Use:   "hello",
	Run: func(cmd *cobra.Command, args []string) {
		cmd.Println("hello called")
	},
}

テストコード

cmd/hello_test.go

package cmd

import (
	"bytes"
	"testing"

	"github.com/spf13/cobra"
)

func executeCommand(root *cobra.Command, args ...string) (output string, err error) {
	buf := new(bytes.Buffer)
	root.SetOut(buf)
	root.SetErr(buf)
	root.SetArgs(args)

	err = root.Execute()
	return buf.String(), err
}

func TestShowCommand(t *testing.T) {
	output, err := executeCommand(rootCmd, "hello")
	if err != nil {
		t.Fatalf("Expected no error, got %v", err)
	}

	expected := "hello called\n"
	if output != expected {
		t.Fatalf("Expected %q, got %q", expected, output)
	}
}

ポイント

  • サブコマンドでは cmd.Println を使って、文字列を os.Stdout に出力しています。 
  • テストコードでは root.SetOut(buf) により、rootCmd とそのサブコマンドの出力先が buf に設定されます。
  • これにより os.Stdout の内容が buf.String() を使って取得できます。

-技術ブログ
-