How to test the passing of arguments in Golang?

Issue

package main

import (
    "flag"
    "fmt"
)

func main() {
    passArguments()
}

func passArguments() string {
    username := flag.String("user", "root", "Username for this server")
    flag.Parse()
    fmt.Printf("Your username is %q.", *username)

    usernameToString := *username
    return usernameToString
}

Passing an argument to the compiled code:

./args -user=bla

results in:

Your username is "bla"

the username that has been passed is displayed.


Aim: in order to prevent that the code needs to be build and run manually every time to test the code the aim is to write a test that is able to test the passing of arguments.


Attempt

Running the following test:

package main

import (
    "os"
    "testing"
)

func TestArgs(t *testing.T) {
    expected := "bla"
    os.Args = []string{"-user=bla"}

    actual := passArguments()

    if actual != expected {
        t.Errorf("Test failed, expected: '%s', got:  '%s'", expected, actual)
    }
}

results in:

Your username is "root".Your username is "root".--- FAIL: TestArgs (0.00s)
    args_test.go:15: Test failed, expected: 'bla', got:  'root'
FAIL
coverage: 87.5% of statements
FAIL    tool    0.008s

Problem

It looks like that the os.Args = []string{"-user=bla is not able to pass this argument to the function as the outcome is root instead of bla

Solution

Per my comment, the very first value in os.Args is a (path to) executable itself, so os.Args = []string{"cmd", "-user=bla"} should fix your issue. You can take a look at flag test from the standard package where they’re doing something similar.

Also, as os.Args is a “global variable”, it might be a good idea to keep the state from before the test and restore it after. Similarly to the linked test:

oldArgs := os.Args
defer func() { os.Args = oldArgs }()

This might be useful where other tests are, for example, examining the real arguments passed when evoking go test.

Answered By – tomasz

Answer Checked By – Timothy Miller (GoLangFix Admin)

Leave a Reply

Your email address will not be published.