用于标准测试的 Golang 模式



编辑:Adrian的建议是有道理的,所以我将我的代码移动到一个函数中,并从我的眼镜蛇块调用该函数:

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()
}
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.comnexampletokenn"))
    // 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.comnTOKEN: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 包令人恐慌并给您错误:读者必须是文件。如果您与使用该软件包结婚,则可以通过在 ui 上禁用屏蔽选项来避免此问题。询问您的第二个输入:

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,
    })

调用测试函数之前,需要设置读取器和编写器。调用后,结果将写入应验证的编写器中。

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)
  }
}

相关内容

  • 没有找到相关文章

最新更新