Как макетировать сеть в кобре. Команда? - PullRequest
0 голосов
/ 09 июля 2019

Я хочу протестировать некоторые кобры. Команды {}, которым обычно требуется доступ к сети. Я хочу смоделировать сетевую часть, но у меня возникают проблемы с поиском шаблона, который позволяет мне писать небольшие интерфейсы и все еще делает то, что я хочу.

cobra.Command будет запускать только функции с подписью (* cobra.Command, args [] string). Это ограничивает то, как я могу передать сетевой клиент (или поддельный сетевой клиент).

Сетевой клиент не может быть переменной пакета, потому что 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 () должен обслуживать каждую кобру. Команда. Что я могу сделать?

...