Cobra + Viper Golang How to test subcommands?
Asked Answered
J

2

12

I am developing an web app with Go. So far so good, but now I am integrating Wercker as a CI tool and started caring about testing. But my app relies heavily on Cobra/Viper configuration/flags/environment_variables scheme, and I do not know how to properly init Viper values before running my test suite. Any help would be much appreciated.

Joinery answered 6/3, 2016 at 13:3 Comment(0)
T
17

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).

Townsville answered 6/3, 2016 at 14:8 Comment(0)
Q
1

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()
    })
}
Quinnquinol answered 23/7, 2019 at 6:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.