vendredi 25 décembre 2015

how to deal with the "fmt" golang library package for CLI testing

Disclaimer: I wish you a merry XMas and I hope my question does not disturb you!

sample.go:

package main

import(
    "fmt"
    "os"
)


type sample struct {
    value int64
}

func (s sample) useful() {
    if s.value == 0 {
        fmt.Println("Error: something is wrong!")
        os.Exit(1)
    } else {
        fmt.Println("May the force be with you!")
    }
}

func main() {
    s := sample{42}
    s.useful()

    s.value = 0
    s.useful()
}

// output:
// May the force be with you!
// Error: something is wrong!
// exit status 1

I did a lot of research on how to use interfaces in golang testing. But so far I was not able to wrap my head around this completely. At least I can not see how interfaces help me when I need to "mock" (apologies for using this word) golang std. library packages like "fmt".

I came up with two scenarios:

  1. use os/exec to test the command line interface
  2. wrap fmt package so I have control and am able to check the output strings

I do not like both scenarios:

  1. I experience going through the actual command line a convoluted and not-performant (see below). Might have portability issues, too.
  2. I believe this is the way to go but I fear that wrapping the fmt package might be a lot of work (at least wrapping the time package for testing turned out a non-trivial task (http://ift.tt/1ItZuDX)).

Actual Question here: Is there another (better/simpler/idiomatic) way? Note: I want to do this in pure golang, I am not interested in the next testing framework.

cli_test.go:

package main

import(
    "os/exec"
    "testing"
)


func TestCli(t *testing.T) {
    out, err := exec.Command("go run sample.go").Output()
    if err != nil {
        t.Fatal(err)
    }
    if string(out) != "May the force be with you!\nError: this is broken and not useful!\nexit status 1" {
        t.Fatal("There is something wrong with the CLI")
    }
}

Aucun commentaire:

Enregistrer un commentaire