Шаблоны Голанга для стандартного тестирования - PullRequest
0 голосов
/ 03 января 2019

РЕДАКТИРОВАТЬ: предложение Адриана имеет смысл, поэтому я переместил свой код в функцию и вызвал функцию из моего блока кобры:

package cmd

import (
    "fmt"
    "log"
    "os"
    "io"

    "github.com/spf13/cobra"
    "github.com/spf13/viper"
    input "github.com/tcnksm/go-input"
)

var configureCmd = &cobra.Command{
    Use:   "configure",
    Short: "Configure your TFE credentials",
    Long:  `Prompts for your TFE API credentials, then writes them to
    a configuration file (defaults to ~/.tgc.yaml`,
    Run: func(cmd *cobra.Command, args []string) {
        CreateConfigFileFromPrompts(os.Stdin, os.Stdout)
    },
}

func CreateConfigFileFromPrompts(stdin io.Reader, stdout io.Writer) {
    ui := &input.UI{
        Writer: stdout,
        Reader: stdin,
    }

    tfeURL, err := ui.Ask("TFE URL:", &input.Options{
        Default:  "https://app.terraform.io",
        Required: true,
        Loop:     true,
        })
    if err != nil {
        log.Fatal(err)
    }
    viper.Set("tfe_url", tfeURL)

    tfeAPIToken, err := ui.Ask(fmt.Sprintf("TFE API Token (Create one at %s/app/settings/tokens)", tfeURL), &input.Options{
        Default:     "",
        Required:    true,
        Loop:        true,
        Mask:        true,
        MaskDefault: true,
        })

    if err != nil {
        log.Fatal(err)
    }
    viper.Set("tfe_api_token", tfeAPIToken)

    configPath := ConfigPath()
    viper.SetConfigFile(configPath)

    err = viper.WriteConfig()

    if err != nil {
        log.Fatal("Failed to write to: ", configPath, " Error was: ", err)
    }

    fmt.Println("Saved to", configPath)
}

Итак, что я могу перейти к этому методу, чтобы проверить, что результат соответствует ожидаемому?

package cmd

import (
  "strings"
  "testing"
)

func TestCreateConfigFileFromPrompts(t *testing.T) {
  // How do I pass the stdin and out to the method?
  // Then how do I test their contents?
  // CreateConfigFileFromPrompts()
}

Ответы [ 2 ]

0 голосов
/ 11 января 2019
func TestCreateConfigFileFromPrompts(t *testing.T) {

    var in bytes.Buffer
    var gotOut, wantOut bytes.Buffer

    // The reader should read to the \n each of two times.
    in.Write([]byte("example-url.com\nexampletoken\n"))

    // wantOut could just be []byte, but for symmetry's sake I've used another buffer
    wantOut.Write([]byte("TFE URL:TFE API Token (Create one at example-url.com/app/settings/tokens)"))

    // I don't know enough about Viper to manage ConfigPath()
    // but it seems youll have to do it here somehow.
    configFilePath := "test/file/location"

    CreateConfigFileFromPrompts(&in, &gotOut)

    // verify that correct prompts were sent to the writer
    if !bytes.Equal(gotOut.Bytes(), wantOut.Bytes()) {
        t.Errorf("Prompts = %s, want %s", gotOut.Bytes(), wantOut.Bytes())
    }

    // May not need/want to test viper's writing of the config file here, or at all, but if so:
    var fileGot, fileWant []byte
    fileWant = []byte("Correct Config file contents:\n URL:example-url.com\nTOKEN:exampletoken")
    fileGot, err := ioutil.ReadFile(configFilePath)
    if err != nil {
        t.Errorf("Error reading config file %s", configFilePath)
    }
    if !bytes.Equal(fileGot, fileWant) {
        t.Errorf("ConfigFile: %s not created correctly got = %s, want %s", configFilePath, fileGot, fileWant)
    }
}

Как подчеркнул @zdebra в комментариях к своему ответу, пакет go-input находится в состоянии паники и выдает ошибку: Reader должен быть файлом. Если вы состоите в браке, чтобы использовать этот пакет, вы можете избежать этой проблемы, отключив параметр маскировки в пользовательском интерфейсе. Попросите второй ввод:

tfeAPIToken, err := ui.Ask(fmt.Sprintf("TFE API Token (Create one at %s/app/settings/tokens)", tfeURL), &input.Options{
        Default:     "",
        Required:    true,
        Loop:        true,
        //Mask:        true, // if this is set to True, the input must be a file for some reason
        //MaskDefault: true,
    })
0 голосов
/ 07 января 2019

Перед вызовом проверяемой функции необходимо настроить устройство чтения и записи.После вызова результат записывается в программу записи, где он должен быть проверен.

package cmd

import (
  "strings"
  "testing"
)

func TestCreateConfigFileFromPrompts(t *testing.T) {
  in := strings.NewReader("<your input>") // you can use anything that satisfies io.Reader interface here
  out := new(strings.Builder) // you could use anything that satisfies io.Writer interface here like bytes.Buffer

  CreateConfigFileFromPrompts(in, out)

  // here you verify the output written into the out
  expectedOutput := "<your expected output>"
  if out.String() != expectedOutput {
    t.Errorf("expected %s to be equal to %s", out.String(), expectedOutput)
  }
}
...