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

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

How to test the passing of arguments in Golang?

问题

  1. package main
  2. import (
  3. "flag"
  4. "fmt"
  5. "os"
  6. "testing"
  7. )
  8. func main() {
  9. passArguments()
  10. }
  11. func passArguments() string {
  12. username := flag.String("user", "root", "Username for this server")
  13. flag.Parse()
  14. fmt.Printf("Your username is %q.", *username)
  15. usernameToString := *username
  16. return usernameToString
  17. }
  18. func TestArgs(t *testing.T) {
  19. expected := "bla"
  20. os.Args = []string{"./args", "-user=bla"}
  21. actual := passArguments()
  22. if actual != expected {
  23. t.Errorf("Test failed, expected: '%s', got: '%s'", expected, actual)
  24. }
  25. }

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

./args -user=bla

结果为:

Your username is "bla"

显示了传递的用户名。


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


尝试

运行以下测试:

  1. package main
  2. import (
  3. "os"
  4. "testing"
  5. )
  6. func TestArgs(t *testing.T) {
  7. expected := "bla"
  8. os.Args = []string{"./args", "-user=bla"}
  9. actual := passArguments()
  10. if actual != expected {
  11. t.Errorf("Test failed, expected: '%s', got: '%s'", expected, actual)
  12. }
  13. }

结果为:

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

问题

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

英文:
  1. package main
  2. import (
  3. "flag"
  4. "fmt"
  5. )
  6. func main() {
  7. passArguments()
  8. }
  9. func passArguments() string {
  10. username := flag.String("user", "root", "Username for this server")
  11. flag.Parse()
  12. fmt.Printf("Your username is %q.", *username)
  13. usernameToString := *username
  14. return usernameToString
  15. }

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:

  1. package main
  2. import (
  3. "os"
  4. "testing"
  5. )
  6. func TestArgs(t *testing.T) {
  7. expected := "bla"
  8. os.Args = []string{"-user=bla"}
  9. actual := passArguments()
  10. if actual != expected {
  11. t.Errorf("Test failed, expected: '%s', got: '%s'", expected, actual)
  12. }
  13. }

results in:

  1. Your username is "root".Your username is "root".--- FAIL: TestArgs (0.00s)
  2. args_test.go:15: Test failed, expected: 'bla', got: 'root'
  3. FAIL
  4. coverage: 87.5% of statements
  5. 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是一个"全局变量",保留测试之前的状态并在测试后恢复可能是一个好主意。就像链接的测试一样:

  1. oldArgs := os.Args
  2. 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:

  1. oldArgs := os.Args
  2. 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:

确定