Cobra + Viper Golang如何测试子命令?

时间:2016-03-06 13:03:55

标签: go tdd viper-go

我正在使用Go开发一个Web应用程序。到目前为止一切顺利,但现在我正在将Wercker整合为CI工具并开始关注测试。但我的应用程序在很大程度上依赖于Cobra / Viper配置/ flags / environment_variables方案,我不知道在运行我的测试套件之前如何正确初始化Viper值。任何帮助将非常感激。

2 个答案:

答案 0 :(得分:13)

当我使用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函数很容易。

您可以看到此here的另一个(非哑)示例(以及对应的测试here)。

答案 1 :(得分:0)

我找到了一种使用多级子命令测试命令的简便方法,虽然不专业,但效果很好。

假设我们有这样的命令

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

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

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

在测试subOfSubCmd时,我们可以这样做:

func TestCmd(t *testing.T) {
convey.Convey("test cmd", t, func() {
    args := []string{"subName", "subOfSub"}
    RootCmd.SetArgs(args)
    RootCmd.Execute()
    })
}