【问题标题】:How to unit test os/exec's cmd.Start() in golang?如何在 golang 中对 os/exec 的 cmd.Start() 进行单元测试?
【发布时间】:2022-01-27 06:45:42
【问题描述】:

我试图在单元测试中模拟 cmd.Start() 并且无法弄清楚

我们需要模拟整个函数还是可以模拟 cmd.Start() 函数?

有人可以帮我吗?

    package main
    
    import (
        "bytes"
        "fmt"
        "os/exec"
    )
    
    var execCommand = exec.Command
    func main() {
        stdout := &bytes.Buffer{}
        cmd := execCommand("cmd")
        syscall.SysProcAttr := &syscall.SysProcAttr{CmdLine: "/S /c C:\\Temp\\test.exe /S C:\\Temp\\test.log"}
        cmd.Stdout = stdout
    
        errs := cmd.Start()
        if errs != nil {
            fmt.Println("command run fialed :", errs)
            fmt.Println("OUTPUT :", stdout.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
}

【问题讨论】:

  • 尝试先关注this approach。尝试限制命令的数量以确保获得所需的输出,然后继续执行更复杂的命令。

标签: go


【解决方案1】:

我无法模拟 cmd.Start(),无论如何我们都不能这样做,下面是对我有用的方法。

    func fakeExecCommand(command string, args ...string) *exec.Cmd {
            cs := []string{"-test.run=TestExecCommandHelper", "--", "ENTER YOUR COMMAND HERE"}
            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 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))
            }
        }

/////////CODE///////

    func printDate() ([]byte, error) {
        cmd := execCommand("date")
        out, err := cmd.CombinedOutput()
        return out, err
    }

参考以下链接:

How to mock exec.Command for multiple unit tests in Go lang?

【讨论】:

    猜你喜欢
    • 2017-02-10
    • 2015-08-21
    • 2021-11-06
    • 2021-10-07
    • 2012-01-08
    • 2018-12-06
    • 2019-11-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多