英文:
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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论