LoginSignup
2
1

More than 1 year has passed since last update.

Cobraのコマンドをテストする

Posted at

概要

CobraはGoでCLIを作成するのにすごく便利です

Cobraで作成したコマンドをテストするにはコツが必要で、以下の記事がとても参考になる

ただ、雛形の修正など手間もあるので、より簡易的にテストする方法をまとめる

コマンドの作成

subというサブコマンドを持ったCLIを作成します

$ go mod init
$ cobra-cli init
$ cobra-cli add sub

$ go run main.go sub
sub called
cmd/sub.go
...
var subCmd = &cobra.Command{
	Use:   "sub",
	Short: "A brief description of your command",
	Long: `A longer description that spans multiple lines and likely contains examples
and usage of using your command. For example:

Cobra is a CLI library for Go that empowers applications.
This application is a tool to generate the needed files
to quickly create a Cobra application.`,
	Run: func(cmd *cobra.Command, args []string) {
		fmt.Println("sub called")
	},
}
...

テストコード

os.Argsにテストしたいサブコマンドを追加して、標準出力はキャプチャしてテストする

cmd/sub_test.go
package cmd

import (
	"bytes"
	"os"
	"testing"
)

var originalArgs = os.Args

func setArgs(arg string) {
	os.Args = append(originalArgs, arg)
}

func resetArgs() {
	os.Args = originalArgs
}

func Test_subCmd(t *testing.T) {
	setArgs("sub")
	defer resetArgs()

	got := PickStdout(t, func() { subCmd.Execute() })
	want := "sub called"
	if got != want {
		t.Errorf("subCmd.Execute() = %v, want = %v", got, want)
	}
}

func PickStdout(t *testing.T, fnc func()) string {
	t.Helper()
	backup := os.Stdout
	defer func() {
		os.Stdout = backup
	}()
	r, w, err := os.Pipe()
	if err != nil {
		t.Fatalf("fail pipe: %v", err)
	}
	os.Stdout = w
	fnc()
	w.Close()
	var buffer bytes.Buffer
	if n, err := buffer.ReadFrom(r); err != nil {
		t.Fatalf("fail read buf: %v - number: %v", err, n)
	}
	s := buffer.String()
	return s[:len(s)-1]
}

これでコマンドのテストができるようになりました

$ go test ./...

参考

最後に

Go強化月間とのこと

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1