我刚刚学习了使用exec.Command()ie, mocking 的单元测试函数exec.Command()。我继续添加更多单元案例,但遇到了无法模拟不同场景输出的问题。
这是hello.go我正在尝试测试的示例代码...
package main
import (
"fmt"
"os/exec"
)
var execCommand = exec.Command
func printDate() ([]byte, error) {
cmd := execCommand("date")
out, err := cmd.CombinedOutput()
return out, err
}
func main() {
fmt.Printf("hello, world\n")
fmt.Println(printDate())
}
Run Code Online (Sandbox Code Playgroud)
下面是测试代码hello_test.go...
package main
import (
"fmt"
"os"
"os/exec"
"testing"
)
var mockedExitStatus = 1
var mockedDate = "Sun Aug 20"
var expDate = "Sun Aug 20"
func fakeExecCommand(command string, args ...string) *exec.Cmd {
cs := []string{"-test.run=TestHelperProcess", "--", command}
cs = append(cs, args...)
cmd := exec.Command(os.Args[0], cs...)
cmd.Env = []string{"GO_WANT_HELPER_PROCESS=1"}
return cmd
}
func TestHelperProcess(t *testing.T) {
if os.Getenv("GO_WANT_HELPER_PROCESS") != "1" {
return
}
// println("Mocked Data:", mockedDate)
fmt.Fprintf(os.Stdout, mockedDate)
os.Exit(mockedExitStatus)
}
func TestPrintDate(t *testing.T) {
execCommand = fakeExecCommand
defer func() { execCommand = exec.Command }()
out, err := printDate()
print("Std out: ", string(out))
if err != nil {
t.Errorf("Expected nil error, got %#v", err)
}
if string(out) != expDate {
t.Errorf("Expected %q, got %q", expDate, string(out))
}
}
func TestPrintDateUnableToRunError(t *testing.T) {
execCommand = fakeExecCommand
defer func() { execCommand = exec.Command }()
mockedExitStatus = 1
mockedDate = "Unable to run date command"
expDate = "Unable to run date command"
out, err := printDate()
print("Std out: ", string(out))
if err != nil {
t.Errorf("Expected nil error, got %#v", err)
}
if string(out) != expDate {
t.Errorf("Expected %q, got %q", expDate, string(out))
}
}
Run Code Online (Sandbox Code Playgroud)
go test第二次测试失败TestPrintDateUnableToRunError...
$ go test hello
Std out: Sun Aug 20Std out: Sun Aug 20--- FAIL: TestPrintDateTomorrow (0.01s)
hello_test.go:62: Expected "Unable to run date command", got "Sun Aug 20"
FAIL
FAIL hello 0.017s
Run Code Online (Sandbox Code Playgroud)
即使我试图mockedDate在测试用例中设置全局值,它仍然会获得初始化时使用的全局值。是否未设置全局值?或者对该全局变量的更改没有更新TestHelperProcess?
我得到了这个问题的解决方案...
全局值没有设置吗?或者对该全局变量的更改没有在 TestHelperProcess 中更新?
由于 in TestPrintDate(),fakeExecCommand被调用而不是 exec.Command ,并且调用fakeExecCommandrunninggo test来运行 only TestHelperProcess(),所以它完全是一个新的调用,其中 onlyTestHelperProcess()将被执行。由于仅TestHelperProcess()调用了,因此未设置全局变量。
解决方案是在 中设置 Env fakeExecCommand,然后在 中检索它TestHelperProcess()并返回这些值。
PS>TestHelperProcess被重命名为TestExecCommandHelper,并且很少有变量被重命名。
package main
import (
"fmt"
"os"
"os/exec"
"strconv"
"testing"
)
var mockedExitStatus = 0
var mockedStdout string
func fakeExecCommand(command string, args ...string) *exec.Cmd {
cs := []string{"-test.run=TestExecCommandHelper", "--", command}
cs = append(cs, args...)
cmd := exec.Command(os.Args[0], cs...)
es := strconv.Itoa(mockedExitStatus)
cmd.Env = []string{"GO_WANT_HELPER_PROCESS=1",
"STDOUT=" + mockedStdout,
"EXIT_STATUS=" + es}
return cmd
}
func TestExecCommandHelper(t *testing.T) {
if os.Getenv("GO_WANT_HELPER_PROCESS") != "1" {
return
}
// println("Mocked stdout:", os.Getenv("STDOUT"))
fmt.Fprintf(os.Stdout, os.Getenv("STDOUT"))
i, _ := strconv.Atoi(os.Getenv("EXIT_STATUS"))
os.Exit(i)
}
func TestPrintDate(t *testing.T) {
mockedExitStatus = 1
mockedStdout = "Sun Aug 201"
execCommand = fakeExecCommand
defer func() { execCommand = exec.Command }()
expDate := "Sun Aug 20"
out, _ := printDate()
if string(out) != expDate {
t.Errorf("Expected %q, got %q", expDate, string(out))
}
}
func TestPrintDateUnableToRunError(t *testing.T) {
mockedExitStatus = 1
mockedStdout = "Unable to run date command"
execCommand = fakeExecCommand
defer func() { execCommand = exec.Command }()
expDate := "Unable to run date command"
out, _ := printDate()
// println("Stdout: ", string(out))
if string(out) != expDate {
t.Errorf("Expected %q, got %q", expDate, string(out))
}
}
Run Code Online (Sandbox Code Playgroud)
go test结果如下...
(故意失败一项测试以表明模拟工作正常)。
go test hello
--- FAIL: TestPrintDate (0.01s)
hello_test.go:45: Expected "Sun Aug 20", got "Sun Aug 201"
FAIL
FAIL hello 0.018s
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5319 次 |
| 最近记录: |