2

I have this code in Go:

 func getPasswordAndUsername(reader io.Reader) (string, string) {
    var username string
    var password string
    r := bufio.NewScanner(reader)
    fmt.Printf("ENTER USERNAME:\n")
    r.Scan()
    username = r.Text()
    fmt.Printf("ENTER PASSWORD:\n")
    r.Scan()
    password = r.Text()
    return username, password
}

Which is great in that it's fully testable without user interaction. As I can build a reader out of both os.Stdin and, eg strings.NewReader(teststring) - but awful in that it echoes the password in actual real-world use. The solutions I have seen of using a particular terminal type don't seem testable to me in the same way - ie I would have to have some code in the function that mutates the execution path depending on the context. Is there a way of ensuring that the function can have a single path of execution?

This is very clearly NOT the same question as how can I suppress password echoes in Go as I have made it clear I have seen the terminal-based code. Instead I am asking for a way to have a function that can run both in interactive mode and inside a test harness where there is no interaction.

Perhaps that isn't possible, but the answer is not simply "use the terminal code".

blackgreen
  • 34,072
  • 23
  • 111
  • 129
adrianmcmenamin
  • 1,081
  • 1
  • 15
  • 44
  • it's hard to understand what exactly are you trying to do or to test. If you want to create unit test you can always create mocks of username and password without using any kind of prints. – Tomer S Nov 04 '22 at 12:35
  • Is this what you need? https://pkg.go.dev/golang.org/x/term#ReadPassword – NotX Nov 04 '22 at 18:02
  • FWIW I haven't been able to find a way to do this and have had to call the function with an additional boolean as a parameter to mark state and then mutate the execution path accordingly. The question will remain open in case someone has an answer though. – adrianmcmenamin Nov 08 '22 at 17:11

0 Answers0