英文:
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"))
关于gbytes和gexec的更多详细信息,请参考以下链接:
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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论