Как вызвать SetOut() для подкоманд в Cobra?

Я пытаюсь протестировать свое приложение CLI, написанное с помощью Cobra, в частности, чтобы проверить, правильно ли записываются подкоманды в STDOUT. Для этого я пытаюсь перенаправить вывод из STDOUT в свой буфер. К сожалению, по какой-то причине функция SetOut() не ведет себя должным образом с подкомандами, полученными через вызов Commands().

Как мне правильно вызвать SetOut() для подкоманд в Cobra?

Вот мой код:

package cmd

import (
    "os"
    "testing"
    "bytes"
    "io/ioutil"
    "github.com/spf13/cobra"
)

func NewCmd() *cobra.Command {
    cmd := &cobra.Command{}
    cmd.AddCommand(NewChildCmd())
    return cmd
}

func NewChildCmd() *cobra.Command {
    cmd := &cobra.Command{
        Use:   "child",
        Run: func(cmd *cobra.Command, args []string) {
                os.Stdout.WriteString("TEST\n")
        },
    }
    return cmd
}

func TestChild(t *testing.T) {
    cmd := NewCmd()
    buffer := new(bytes.Buffer)

    subCommands := cmd.Commands()
    for i := range subCommands {
        subCommands[i].SetOut(buffer)
    }

    cmd.SetOut(buffer)
    cmd.SetArgs([]string{"child"})
    cmd.Execute()
    out, err := ioutil.ReadAll(buffer)
    if err != nil {
        t.Fatal(err)
    }
    if string(out) != "child" {
        t.Fatalf("Expected \"TEST\", got \"%s\"", string(out))
    }
}

И вот тестовый вывод:

TEST
--- FAIL: TestChild (0.00s)
    cmd/my_test.go:44: Expected "TEST", got ""
FAIL
FAIL    cmd 0.004s
FAIL

person Petr    schedule 25.03.2021    source источник


Ответы (1)


Судя по всему, SetOut() не может изменить вывод, отправляемый напрямую в os.Stdout, вместо этого приходится использовать cmd.Println(), тогда все работает как положено.

person Petr    schedule 25.03.2021