英文:
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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论