0

I work on a small CLI application. I am trying to write unit tests. I have a function that renders some output as a table to the command line using fmt.Println/fmt.Printf. I am wondering how I can capture that output in a unit test to make sure I am getting what is expected? Below is just a barebone skeleton that somewhat represents what I am trying to achieve.

main.go

package main

import (
    "fmt"
    "io"
)

func print() {
    fmt.Println("Hello world")
}

func main() {
    print()
}

main_test.go

package main

import "testing"

func TestPrint(t *testing.T) {
    expected := "Hello world"
    print() // somehow capture the output
    // if got != expected {
    //  t.Errorf("Does not match")
    // }
}

I have tried a few approaches such as How to check a log/output in go test? but with minimal luck but, that could be due to misunderstanding on my end.

Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
jsm1th
  • 469
  • 2
  • 4
  • 16

1 Answers1

3

you got to inject, somehow, the destination writer.

Your API is insufficient because it does not allow injection.

In this modified code, the destination writer is given as an argument, but other API implementation decision are possible.

package main

import (
    "fmt"
    "io"
)

func print(dst io.Writer) {
    fmt.Fprintln(dst, "Hello world")
}

func main() {
    print(os.Stdout)
}

you can test doing so

package main

import "testing"

func TestPrint(t *testing.T) {
    expected := "Hello world"
    var b bytes.Buffer    
    print(&b) // somehow capture the output
    // if b.String() != expected {
    //  t.Errorf("Does not match")
    // }
}

bytes.Buffer implements io.Writer and can be used as a stub to capture execution results.

https://golang.org/pkg/bytes/#Buffer

  • This is great, thank you. I was able to use this approach in my actual application I am working on and everything seems to be working as I wanted. – jsm1th Oct 22 '19 at 13:17
  • 2
    FYI if dealing with console output, you need to take into account the newline i.e. `expected := "Hello world\n"` – colm.anseo Oct 22 '19 at 14:17