如何在cobra.Command中模拟网络?

时间:2019-07-09 18:11:32

标签: unit-testing go go-cobra

我想测试一些通常需要网络访问的cobra.Commands {}。我想模拟网络部分,但是我很难找到一种模式,该模式可以让我编写小型接口,并且仍然可以执行我想做的事情。

cobra.Command将仅运行带有签名的功能(* cobra.Command,args []字符串)。这限制了我如何传入网络客户端(或模拟的网络客户端)。

网络客户端不能是程序包变量,因为viper需要首先解析命令行参数。所以我有一个功能:

func newNode() otherpkg.NodeInterface {
    return otherpkg.NewNode(otherpkg.Config.Node.URL, debug)
}

newNode()仅是网络,因此我在测试时需要解决它。我将网络初始化保留在cobra.Command的匿名函数中,然后将实际逻辑移至ttlFunc()。我只测试ttlFunc,不测试ttlCmd。这样,我可以测试实际逻辑或使用GetHeighter接口传递模拟网络客户端。

var ttlCmd = &cobra.Command{
    Use:   "ttl",
    Short: "Get the absolute TTL for a Transaction",
    Args:  cobra.ExactArgs(0),
    RunE: func(cmd *cobra.Command, args []string) error {
        node := newNode()
        return ttlFunc(node, args)
    },
}

func ttlFunc(conn otherpkg.GetHeighter, args []string) (err error) {
    height, err := conn.GetHeight()
    if err != nil {
        errFinal := fmt.Errorf("Error getting height from the node: %v", err)
        return errFinal
    }
    ttl = height + otherpkg.Config.Client.TTL
    fmt.Println(ttl)
    return nil
}

如果现在模拟了conn.GetHeight,则可以看到在ttlFunc()之类的简单函数中,如果仅从函数返回错误,则不会进行任何测试。因此,我想使用cobra.Command SetIn(),SetOut()并测试ttlCmd,并针对stdout进行断言。

但是,如果我离开了ttlCmd()/ ttlFunc()模式,那么我不知道如何在不混合测试代码和有用代码的情况下,将客户端/模拟客户端提供给需要的函数像这样:

func newNode() otherpkg.NodeInterface {
        if !online{
            return &MockNode{}
        }
    return otherpkg.NewNode(otherpkg.Config.Node.URL, debug)
}

另外,otherpkg.NodeInterface很大,因此MockNode将自己维护。我知道在Go中应该保持接口较小,但是此newNode()应该为每个cobra.Command服务。我该怎么办?

0 个答案:

没有答案