Test Exec, который требует интерактивного ввода в Golang - PullRequest
0 голосов
/ 01 февраля 2019

Я пытаюсь использовать fzf в коде Go.Я сослался на пример, приведенный здесь автором.Когда я пытался написать тест для функции, она застревает, поскольку fzf требует интерактивного ввода.

Код:

func withFilter(command string, input func(in io.WriteCloser)) []string {
    shell := os.Getenv("SHELL")
    if len(shell) == 0 {
        shell = "sh"
    }
    cmd := exec.Command(shell, "-c", command)
    cmd.Stderr = os.Stderr
    in, _ := cmd.StdinPipe()
    go func() {
        input(in)
        in.Close()
    }()
    result, _ := cmd.Output()
    return strings.Split(string(result), "\n")
}

func filter() []string {
    filtered := withFilter("fzf -m", func(in io.WriteCloser) {
        for i := 0; i < 10; i++ {
            fmt.Fprintln(in, i)
            time.Sleep(5 * time.Millisecond)
        }
    })

    return filtered
}

Тест:

func TestFilter(t *testing.T) {
    assert.Equal(t, []string{"1", "2", "3"}, filter())
}

Iпопытался отладить и заметил, что он застрял на cmd.Output().Если копнуть немного глубже, то похоже, что команда ждет ввода бесконечно, однако я не уверена, как обеспечить это программно.Я пытался написать \n в os.Stdin, но это не сработало.

Любые указатели или объяснения будут оценены.Спасибо.

1 Ответ

0 голосов
/ 01 февраля 2019

Прелесть go: его io.Reader / io.Writer интерфейсы.

Вы должны указать, откуда должен читаться ваш метод withFilter (и, соответственно, filter).Итак, in должно быть предоставлено.

// example

func readFrom(reader io.Reader) {
    r := bufio.NewScanner(reader)

    for r.Scan() {
        fmt.Println("got", r.Text())
    }

    fmt.Println("Done.")
}

func main() {
    const input = "Now is the winter of our discontent,\nMade glorious summer by this sun of York.\n"

    readFrom(strings.NewReader(input))

    // okay, with stdin
    readFrom(os.Stdin)

}

Как видите, первый readFrom полностью тестируемый, вы просто меняете переменную input на то, что вы хотите протестировать.Второй readFrom вернется, только когда stdin будет закрыт.

Решение - , а не для записи в os.Stdin.Рассмотрим os.Stdin подробности реализации в вашей ОС, а не то, что вы должны включить в свое тестирование.

https://play.golang.org/p/D2wzHYrV2TM (os.Stdin закрыт на игровой площадке)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...