【问题标题】:Testing Stdout with go and ginkgo用 go 和 ginkgo 测试标准输出
【发布时间】:2014-09-04 12:07:14
【问题描述】:

在这里,我正在尝试在 go 命令行应用程序上执行 BDD 的第一步。 我正在使用 Ginkgo,它包装了 testing.go,让你做更具表现力的 BDD。 https://github.com/onsi/ginkgo

我在读取标准输出以对其进行断言时遇到问题。

发现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"))
        })
})

【问题讨论】:

    标签: go ginkgo


    【解决方案1】:

    测试标准输出可能很棘手。您有多项选择。

    您可以在测试期间覆盖 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"))
            })
    })
    

    或者您可以将编写器传递给您的函数:

    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)
    }
    

    【讨论】:

    • 我对银杏不熟悉,在第二种情况下,如果您通过作家,那么@Onsi 解决方案可能会更好。甚至可以将 gbytes 包装到 *os.File 中以覆盖 os.Stdout。
    【解决方案2】:

    这是依赖注入的经典用例。您可以使用 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,在这种情况下,我建议使用gexecgexec.Build 二进制文件,然后运行gexec.Start 命令,生成的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

    【讨论】:

    • gexec.Start一般什么时候调用?例如,我想要多个 Ifs 测试一个二进制文件的单次运行。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-11-30
    • 2014-08-05
    • 1970-01-01
    • 2013-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多