如何在Golang中测试参数的传递?

huangapple go评论80阅读模式
英文:

How to test the passing of arguments in Golang?

问题

package main

import (
	"flag"
	"fmt"
	"os"
	"testing"
)

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
}

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

	actual := passArguments()

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

将参数传递给编译后的代码:

./args -user=bla

结果为:

Your username is "bla"

显示了传递的用户名。


**目标:**为了避免每次都需要手动构建和运行代码来测试代码,目标是编写一个能够测试参数传递的测试。


尝试

运行以下测试:

package main

import (
	"os"
	"testing"
)

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

	actual := passArguments()

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

结果为:

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

问题

看起来os.Args = []string{"./args", "-user=bla"}无法将该参数传递给函数,结果是root而不是bla

英文:
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

答案1

得分: 31

根据我的评论,os.Args中的第一个值是可执行文件本身的路径,所以os.Args = []string{"cmd", "-user=bla"}应该可以解决你的问题。你可以参考标准包中的flag test,他们在那里做了类似的操作。

另外,由于os.Args是一个"全局变量",保留测试之前的状态并在测试后恢复可能是一个好主意。就像链接的测试一样:

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

这在其他测试中可能会很有用,例如在调用go test时检查传递的实际参数。

英文:

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.

答案2

得分: 0

这是足够旧但仍然被搜索到的内容,尽管它看起来已经过时了。
因为Go 1.13改变了一些东西

我发现这个改变很有帮助,将flag.*()放在init()中,将flag.Parse()放在Test*()中。

-args不能在-<test-args>=<val>之后使用,只能使用<test-args>,否则test-args将被视为go test的命令行参数,而不是你的Test*的参数。

英文:

This is old enough but still searched out, while it seems out dated.
Because Go 1.13 changed sth.

I find this change helpful, putting flag.*() in init() and flag.Parse() in Test*()

-args cannot take -<test-args>=<val> after it, but only <test-args>, otherwise the test-args will be taken as go test's command line parameter, instead of your Test*'s

huangapple
  • 本文由 发表于 2015年11月16日 02:25:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/33723300.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定