【问题标题】:How to unit test CLI output [duplicate]如何对 CLI 输出进行单元测试
【发布时间】:2019-10-22 21:15:25
【问题描述】:

我在开发一个小型 CLI 应用程序。我正在尝试编写单元测试。我有一个函数可以使用fmt.Println/fmt.Printf 将一些输出作为表格呈现给命令行。我想知道如何在单元测试中捕获该输出以确保我得到预期的结果?下面只是一个准系统骨架,在某种程度上代表了我想要实现的目标。

main.go

package main

import (
    "fmt"
    "io"
)

func print() {
    fmt.Println("Hello world")
}

func main() {
    print()
}

main_test.go

package main

import "testing"

func TestPrint(t *testing.T) {
    expected := "Hello world"
    print() // somehow capture the output
    // if got != expected {
    //  t.Errorf("Does not match")
    // }
}

我尝试了一些方法,例如How to check a log/output in go test?,但运气不佳,但这可能是由于我的误解。

【问题讨论】:

  • 接口是你测试的好朋友。
  • @Volker:一般来说是好的建议,但并非总是可行。

标签: unit-testing go testing


【解决方案1】:

你必须以某种方式注入目标作家。

您的 API 不足,因为它不允许注入。

在此修改后的代码中,目标编写器作为参数给出,但其他 API 实现决策也是可能的。

package main

import (
    "fmt"
    "io"
)

func print(dst io.Writer) {
    fmt.Fprintln(dst, "Hello world")
}

func main() {
    print(os.Stdout)
}

你可以测试一下

package main

import "testing"

func TestPrint(t *testing.T) {
    expected := "Hello world"
    var b bytes.Buffer    
    print(&b) // somehow capture the output
    // if b.String() != expected {
    //  t.Errorf("Does not match")
    // }
}

bytes.Buffer 实现了io.Writer,可以用作存根来捕获执行结果。

https://golang.org/pkg/bytes/#Buffer

【讨论】:

  • 这太好了,谢谢。我能够在我正在处理的实际应用程序中使用这种方法,并且一切似乎都按我的意愿工作。
  • 仅供参考,如果处理控制台输出,您需要考虑换行符,即expected := "Hello world\n"
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-01-08
  • 1970-01-01
  • 2019-11-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多