加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

如何处理用于CLI测试的“fmt”golang库包

发布时间:2020-12-16 19:26:30 所属栏目:大数据 来源:网络整理
导读:免责声明:祝你圣诞快乐,我希望我的问题不会打扰你! sample.go: package mainimport( "fmt" "os")type sample struct { value int64}func (s sample) useful() { if s.value == 0 { fmt.Println("Error: something is wrong!") os.Exit(1) } else { fmt.Pr
免责声明:祝你圣诞快乐,我希望我的问题不会打扰你!

sample.go:

package main

import(
    "fmt"
    "os"
)


type sample struct {
    value int64
}

func (s sample) useful() {
    if s.value == 0 {
        fmt.Println("Error: something is wrong!")
        os.Exit(1)
    } else {
        fmt.Println("May the force be with you!")
    }
}

func main() {
    s := sample{42}
    s.useful()

    s.value = 0
    s.useful()
}

// output:
// May the force be with you!
// Error: something is wrong!
// exit status 1

我做了很多关于如何在golang测试中使用接口的研究.但到目前为止,我还是无法彻底解决这个问题.至少我无法看到界面如何帮助我,当我需要“模拟”(道歉使用这个词)golang std.像“fmt”这样的库包.

我想出了两个场景:

>使用os / exec测试命令行界面
>包装fmt包所以我有控制权并且能够检查输出字符串

我不喜欢这两种情况:

>我经历了实际的命令行一个复杂而不具备性能(见下文).也可能有可移植性问题.
>我相信这是要走的路,但我担心包装fmt包可能需要做很多工作(至少包装测试的时间包结果是一项非常重要的任务(https://github.com/finklabs/ttime)).

这里的实际问题:还有另一种(更好/更简单/惯用)方式吗?
注意:我想在纯golang中执行此操作,我对下一个测试框架不感兴趣.

cli_test.go:

package main

import(
    "os/exec"
    "testing"
)


func TestCli(t *testing.T) {
    out,err := exec.Command("go run sample.go").Output()
    if err != nil {
        t.Fatal(err)
    }
    if string(out) != "May the force be with you!nError: this is broken and not useful!nexit status 1" {
        t.Fatal("There is something wrong with the CLI")
    }
}
Kerningham’s Book的第11章为这个问题提供了一个很好的解决方案.
诀窍是将对fmt.Printline()的调用更改为调用
fmt.Fprint(out,…)其中out初始化为os.Stdout

这可以在测试工具中覆盖到new(bytes.Buffer)允许
测试以捕获输出.

见https://github.com/adonovan/gopl.io/blob/master/ch11/echo/echo.go和
https://github.com/adonovan/gopl.io/blob/master/ch11/echo/echo_test.go

由OP编辑…
sample.go:

package main


import(
    "fmt"
    "os"
    "io"
)


var out io.Writer = os.Stdout // modified during testing
var exit func(code int) = os.Exit

type sample struct {
    value int64
}


func (s sample) useful() {
    if s.value == 0 {
        fmt.Fprint(out,"Error: something is wrong!n")
        exit(1)
    } else {
        fmt.Fprint(out,"May the force be with you!n")
    }
}


func main() {
    s := sample{42}
    s.useful()

    s.value = 0
    s.useful()
}

// output:
// May the force be with you!
// Error: this is broken and not useful!
// exit status 1

cli_test.go:

package main

import(
    "bytes"
    "testing"
)


func TestUsefulPositive(t *testing.T) {
    bak := out
    out = new(bytes.Buffer)
    defer func() { out = bak }()

    s := sample{42}
    s.useful()
    if out.(*bytes.Buffer).String() != "May the force be with you!n" {
        t.Fatal("There is something wrong with the CLI")
    }

}


func TestUsefulNegative(t *testing.T) {
    bak := out
    out = new(bytes.Buffer)
    defer func() { out = bak }()
    code := 0
    osexit := exit
    exit = func(c int) { code = c }
    defer func() { exit = osexit }()

    s := sample{0}
    s.useful()
    if out.(*bytes.Buffer).String() != "Error: something is wrong!n" {
        t.Fatal("There is something wrong with the CLI")
    }
    if code != 1 {
        t.Fatal("Wrong exit code!")
    }
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读