Cobra + Viper Golang How to test subcommands?

i have found an easy way to test commands with multiple level sub commands, it is not professional but it worked well.

assume we have a command like this

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)

When testing the subOfSubCmd we can do this way:

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

When I use Cobra/Viper or any other combination of CLI helpers, my way of doing this is to have the CLI tool run a function whose sole purpose will be to get arguments and pass them to another method who will do the actual work.

Here is a short (and dumb) example using 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)
        }
}

Here, the Boom function is hard to test, but the boom one is easy.

You can see another (non-dumb) example of this here (and the correspond test here).

Tags:

Tdd

Go

Viper Go