测试使用Go和Ginkgo进行标准输出

huangapple go评论73阅读模式
英文:

Testing Stdout with go and ginkgo

问题

这是我翻译好的内容:

这里我正在尝试在Go语言的命令行应用程序上进行BDD(行为驱动开发)的初步尝试。

我正在使用Ginkgo,它包装了testing.go,并允许您进行更具表现力的BDD。https://github.com/onsi/ginkgo

我在读取stdout并对其进行断言时遇到了问题。

pkg/testing的示例中发现在运行之前对输出进行了存根处理,但我找不到读取该输出的方法:http://golang.org/src/pkg/testing/example.go

这是我想要做的:

cli.go

package cli

import "fmt"

func Run() {
    fmt.Println("Running cli")
}

cli_test.go

package cli_test

import (
    . "github.com/altoros/bosh_deployer_cli/lib/cli"

    . "github.com/onsi/ginkgo"
    . "github.com/onsi/gomega"
)

var _ = Describe("Cli", func() {
    It("should parse update stemcell flag", func() {
        Run()
        Expect(stdout).To(Equal("running cli"))
    })
})
英文:

here I am making my first steps in go trying to do BDD on a go command line app.
I am using Ginkgo, which wraps testing.go and lets you do more expressive BDD. https://github.com/onsi/ginkgo

I am having issues in reading the stdout to do an assertion on it.

Found that on pkg/testing example do stub the output before running but I can not find the way to read that output: http://golang.org/src/pkg/testing/example.go

This is what I would like to do:

cli.go

 package cli
  
 import "fmt"
  
 func Run() {
        fmt.Println("Running cli")
 }

cli_test.go

package cli_test

import (
        . "github.com/altoros/bosh_deployer_cli/lib/cli"

        . "github.com/onsi/ginkgo"
        . "github.com/onsi/gomega"
)

var _ = Describe("Cli", func() {
        It("should parse update stemcell flag", func() {
                Run()
                Expect(stdout).To(Equal("running cli"))
        })
})

答案1

得分: 8

测试Stdout可能会很棘手。你有多种选择。

你可以在测试期间覆盖os.Stdout:(记得检查错误)

var _ = Describe("Cli", func() {
    It("should parse update stemcell flag", func() {
        r, w, _ := os.Pipe()
        tmp := os.Stdout
        defer func() {
            os.Stdout = tmp
        }()
        os.Stdout = w
        go func() {
            Run()
            w.Close()
        }()
        stdout, _ := ioutil.ReadAll(r)
        Expect(string(stdout)).To(Equal("Running cli\n"))
    })
})

或者你可以将一个writer传递给你的函数:

cli.go

package cli

import (
    "fmt"
    "io"
)

func Run(w io.Writer) {
    fmt.Fprintln(w, "Running cli")
}

cli_test.go

package cli_test

import (
    . "cli"
    "io"
    "io/ioutil"

    . "github.com/onsi/ginkgo"
    . "github.com/onsi/gomega"
)

var _ = Describe("Cli", func() {
    It("should parse update stemcell flag", func() {
        r, w := io.Pipe()
        go func() {
            Run(w)
            w.Close()
        }()
        stdout, _ := ioutil.ReadAll(r)
        Expect(string(stdout)).To(Equal("Running cli\n"))
    })
})

main.go

package main

import (
    "cli"
    "os"
)

func main() {
    cli.Run(os.Stdout)
}
英文:

Testing Stdout can be tricky. You have multiple choice.

You can override os.Stdout during your test: (think to check the errors)

var _ = Describe("Cli", func() {
        It("should parse update stemcell flag", func() {
                r, w, _ := os.Pipe()
                tmp := os.Stdout
                defer func() {
                        os.Stdout = tmp
                }()
                os.Stdout = w
                go func() {
                        Run()
                        w.Close()
                }()
                stdout, _ := ioutil.ReadAll(r)
                Expect(string(stdout)).To(Equal("Running cli\n"))
        })
})

or you can pass a writer to your function:

##cli.go

package cli

import (
        "fmt"
        "io"
)

func Run(w io.Writer) {
        fmt.Fprintln(w, "Running cli")
}

##cli_test.go

package cli_test

import (
        . "cli"
        "io"
        "io/ioutil"

        . "github.com/onsi/ginkgo"
        . "github.com/onsi/gomega"
)

var _ = Describe("Cli", func() {
        It("should parse update stemcell flag", func() {
                r, w := io.Pipe()
                go func() {
                        Run(w)
                        w.Close()
                }()
                stdout, _ := ioutil.ReadAll(r)
                Expect(string(stdout)).To(Equal("Running cli\n"))
        })
})

##main.go

package main

import (
        "cli"
        "os"
)

func main() {
        cli.Run(os.Stdout)
}

答案2

得分: 4

这是一个经典的依赖注入的用例。你可以使用Gomega中的gbytes.Buffer,并在单元测试中使用类似以下的代码:

var _ = Describe("Cli", func() {
    It("should parse update stemcell flag", func() {
        buffer := gbytes.NewBuffer()
        Run(buffer)
        Expect(buffer).To(gbytes.Say("Running cli\n"))
    })
})

除非你正在对cli进行集成测试,我建议你使用gexec来构建二进制文件并运行命令,生成的gexec.Session对象将捕获stdout并将其作为gbytes.Buffer可用,这样你可以编写:

Expect(session).To(gbytes.Say("Running cli\n"))

关于gbytesgexec的更多详细信息,请参考以下链接:

http://onsi.github.io/gomega/#gbytes-testing-streaming-buffers

http://onsi.github.io/gomega/#gexec-testing-external-processes

英文:

This is a classic usecase for dependency injection. You can use a gbytes.Buffer from Gomega and have something like this for a unit test:

var _ = Describe("Cli", func() {
        It("should parse update stemcell flag", func() {
                buffer := gbytes.NewBuffer()
                Run(buffer)
                Expect(buffer).To(gbytes.Say("Running cli\n"))
        })
})

Unless you're integration testing the cli, which case I'd recommend using gexec to gexec.Build the binary and then run gexec.Start the command, the resulting gexec.Session object will capture stdout and make it available as a gbytes.Buffer allowing you, again, to write:

Expect(session).To(gbytes.Say("Running cli\n")

More details on gbytes and gexec here:

http://onsi.github.io/gomega/#gbytes-testing-streaming-buffers

http://onsi.github.io/gomega/#gexec-testing-external-processes

huangapple
  • 本文由 发表于 2014年9月2日 00:17:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/25609734.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定