如何在Golang中对os/exec的cmd.Start()进行单元测试?

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

How to unit test os/exec's cmd.Start() in golang?

问题

我正在尝试在单元测试中模拟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())
	}

}


**Unit Test:**

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
}

请注意,我只会返回翻译好的部分,不会回答关于翻译的问题。

英文:

I'm trying to mock cmd.Start() in Unit test and could not able figure out

Do we need to mock the entire function or can we mock cmd.Start() function?

Can someone help me in this?

    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())
    	}
    
    }

Unit Test:

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
}

答案1

得分: 0

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

func fakeExecCommand(command string, args ...string) *exec.Cmd {
    cs := []string{"-test.run=TestExecCommandHelper", "--", "在这里输入你的命令"}
    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))
    }
}

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

参考以下链接:

https://stackoverflow.com/questions/45789101/how-to-mock-exec-command-for-multiple-unit-tests-in-go-lang

英文:

I was not able to mock cmd.Start(), we cannot do that anyway and below is the way which worked for me.

    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
    }

Referred below link :

https://stackoverflow.com/questions/45789101/how-to-mock-exec-command-for-multiple-unit-tests-in-go-lang

huangapple
  • 本文由 发表于 2022年1月27日 14:45:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/70874391.html
匿名

发表评论

匿名网友

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

确定