Skip to content

Instantly share code, notes, and snippets.

@sha1n
Created May 25, 2021 09:50
Show Gist options
  • Save sha1n/d9169c48aafdd478a233fe2a8a714f4c to your computer and use it in GitHub Desktop.
Save sha1n/d9169c48aafdd478a233fe2a8a714f4c to your computer and use it in GitHub Desktop.
An emulated STDIN reader for user input testing in Go
package test
import (
"bytes"
"fmt"
"strings"
)
type EmulatedStdinReader struct {
buf *bytes.Buffer
lines []string
nextLineIndex int
}
func NewEmulatedStdinReader(content string) *EmulatedStdinReader {
emulatedReader := &EmulatedStdinReader{
buf: new(bytes.Buffer),
lines: strings.Split(content, "\n"),
nextLineIndex: 0,
}
return emulatedReader
}
func (s *EmulatedStdinReader) Read(buf []byte) (int, error) {
if s.buf.Len() == 0 && s.nextLineIndex < len(s.lines) {
s.buf.Reset()
s.buf.WriteString(fmt.Sprintf("%s\n", s.lines[s.nextLineIndex]))
s.nextLineIndex++
}
return s.buf.Read(buf)
}

Here is an example of how EmulatedStdinReader can be used in a test.

// This is what the program use to read from stdin normally
var StdinReader io.Reader = io.Stdin


func TestIt(t *testing.T) {
  userInput := `yes
no
I don't know
`  
  teardown := givenStdInWith(userInput)
  defer teardown()

  
}

func givenStdInWith(content string) func() {
  // We replace the gloabl stdin reader with the emulated one
  StdinReader = test.NewEmulatedStdinReader(content)

  restore := func() {
    // we restore the original one when we're done
    StdinReader = os.Stdin
  }

  return restore
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment