Mocking command line flags and stdin in Go
I recently wrote a program where I wanted to mock command line flags and stdin for testing.
Normally to parse flags in Go you call flag.Parse()
. If you look at the source code you'll see that it's just a wrapper function around flag.CommandLine.Parse(os.Args[1:])
. Where CommandLine is the default flagset created for you. The fact that Parse()
here accepts arguments is exactly what I'm looking for. I just need to write my own wrapper function around this and change the slice that gets passed in to Parse()
.
func setupInputs(args []string) {
a := os.Args[1:]
if args != nil {
a = args
}
flag.CommandLine.Parse(a)
}
My program also reads from stdin. To mock this I created a pointer variable of type file. This matches the same type signature as os.Stdin
. Then in my program I simply refer to this variable when I want to read or write from stdin.
Here I expand the setupInputs
function above to handle setting up stdin.
var stdin *os.File
func setupInputs(args []string, file *os.File) {
... // Code from above function removed to make reading clearer
if file != nil {
stdin = file
} else {
stdin = os.Stdin
}
}
In my tests I simply create a temporary file, write to it and then pass it into the setup function. Like so:
// Create temporary file
file, _ := ioutil.TempFile(os.TempDir(), "stdin")
defer os.Remove(file.Name())
// Write to it
file.WriteString("content from stdin")
// Pass it in
setupInputs([]string{}, file)
To see examples of using this technique have a look at my tests on github
If you have any thoughts about this and want to contact me send an email to [email protected]