Cobra + Viper Golang Как проверить подкоманды?

Я занимаюсь разработкой веб-приложения на Go. Пока все хорошо, но теперь я интегрирую Wercker как инструмент CI и начал заботиться о тестировании. Но мое приложение в значительной степени зависит от схемы Cobra/Viper configuration/flags/environment_variables, и я не знаю, как правильно инициализировать значения Viper перед запуском моего набора тестов. Любая помощь приветствуется.

3 ответа

Решение

Когда я использую Cobra/Viper или любую другую комбинацию помощников CLI, мой способ сделать это - заставить инструмент CLI запустить функцию, единственной целью которой будет получение аргументов и передача их другому методу, который будет выполнять реальную работу.

Вот короткий (и глупый) пример использования Cobra:

package main

import (
        "fmt"
        "os"

        "github.com/spf13/cobra"
)

func main() {
        var Cmd = &cobra.Command{
                Use:   "boom",
                Short: "Explode all the things!",
                Run:   Boom,
        }

        if err := Cmd.Execute(); err != nil {
                fmt.Println(err)
                os.Exit(-1)
        }
}

func Boom(cmd *cobra.Command, args []string) {
        boom(args...)
}

func boom(args ...string) {
        for _, arg := range args {
                println("boom " + arg)
        }
}

Здесь Boom Функцию сложно проверить, но boom одно легко.

Вы можете увидеть другой (не тупой) пример этого здесь (и соответствующий тест здесь).

Я сам боролся с этим и, наконец, написал статью после того, как добился этого.

Вы можете проверить это здесь - https://g14a.github.io/posts/Testing-Cobra-Subcommands/

Я мог бы это прокомментировать, но, к сожалению, у меня недостаточно репутации.

Я нашел простой способ тестировать команды с помощью многоуровневых подкоманд, это непрофессионально, но сработало хорошо.

Предположим, у нас есть такая команда

RootCmd = &cobra.Command{
            Use:   "cliName",
            Short: "Desc",
    }

SubCmd = &cobra.Command{
            Use:   "subName",
            Short: "Desc",
    }

subOfSubCmd = &cobra.Command{
            Use:   "subOfSub",
            Short: "Desc",
            Run: Exec
    }

//commands relationship
RootCmd.AddCommand(SubCmd)
SubCmd.AddCommand(subOfSubCmd)

При тестировании subOfSubCmd мы можем сделать так:

func TestCmd(t *testing.T) {
convey.Convey("test cmd", t, func() {
    args := []string{"subName", "subOfSub"}
    RootCmd.SetArgs(args)
    RootCmd.Execute()
    })
}
Другие вопросы по тегам