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