Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

golang testing command line arguments

Tags:

go

I want to test different (correct/incorrect) command line arguments passed to my CLI program, but I am not sure how to achieve this with go/testing package because I am getting flag redefined error. Looks like it happens because flag.Parse() can be called only once. What is the proper approach to test different command line arguments passed into the go program? Is there is any way to define something like setup()/teardown() or run every case in isolation (but in the same file)?

Here is my code:

Function to test:

func (p *Params) Parse() (*Params, error) {
        param1Ptr := flag.String("param1", "default", "param1 desc")
        param2Ptr := flag.String("param2", "default", "param1 desc")
        ...
        ... 
        flag.Parse()
        ...

}

Test file:

package main

import (
        "os"
        "testing"
)


func TestParam1(t *testing.T) {
        os.Args = []string{"cmd", "-param1", "incorrect", "-param2", "correct"}
        params := Params{}
        _, err := params.Parse()
        ...
        ... 
}

func TestParam2(t *testing.T) {
        os.Args = []string{"cmd", "-param1", "correct", "-param2", "incorrect"}
        params := Params{}
        _, err := params.Parse()
        ...
        ... 
}
like image 261
user1453428 Avatar asked Dec 10 '18 13:12

user1453428


1 Answers

Don't use the global FlagSet object in the flags package. Create your own FlagSet as a field of Params: https://golang.org/pkg/flag/#FlagSet

All that flag.String et al do is pass through the function call to a global FlagSet object in the flag package (specifically flag.CommandLine is the variable). This is easy to use but not a generally good practice. Using your own flagset would avoid the issues you described as well as other potential side effects from using global variables.

like image 79
Adrian Avatar answered Oct 10 '22 21:10

Adrian