我在golang库中有一些测试助手代码,我想在各种子包中进行测试时使用它们。 但是,我遇到了障碍: 要使用test_helpers_test.go的代码,我必须导入外部包。 但是当我从something_test.go导入外包时,它会抱怨“导入循环不允许在测试中” 所以我尝试为 ...
提示:本站收集StackOverFlow近2千万问答,支持中英文搜索,鼠标放在语句上弹窗显示对应的参考中文或英文, 本站还提供 中文繁体 英文版本 中英对照 版本,有任何建议请联系yoyou2525@163.com。
我是golang的新手,我在我的一个项目中使用了名为promptui( https://github.com/manifoldco/promptui )的交互式提示。 我已经为这个项目编写了几个单元测试,但我正在努力解决这个需要输入的特定包的测试方法。
例如,我将如何测试以下代码行(封装在函数中):
func setEmail() string {
prompt := promptui.Prompt{Label: "Input your Email",
Validate: emailValidations,
}
email, err := prompt.Run()
if err != nil {
color.red("failed getting email")
os.exit(3)
}
return email
}
我想我需要以某种方式模拟stdin,但无法找出在测试中做到这一点的最佳方法。
您不应该尝试测试promptui
因为它应该由作者测试。
你可以测试什么:
promptui.Prompt
时发送正确的参数 promptui.Prompt
promptui.Prompt
结果 如您所见,所有这些测试都不验证promptui.Prompt
是否在内部正常工作。
可以组合测试#2和#3。 您需要针对模拟运行代码,如果结果正确,您可以相信#2和#3都是正确的。
创建模拟:
type Runner interface {
Run() (int, string, error)
}
type promptMock struct {
// t is not required for this test, but it is would be helpful to assert input parameters if we have it in Run()
t *testing.T
}
func (p promptMock) Run() (int, string, error) {
// return expected result
return 1, "", nil
}
您将需要单独的模拟来测试错误流。
更新你的代码以注入mock:
func setEmail(runner Runner) string {
email, err := runner.Run()
if err != nil {
color.red("failed getting email")
os.exit(3)
}
return email
}
现在它是可测试的。
创建创建prompt
函数:
func getRunner() promptui.Prompt {
return promptui.Prompt{Label: "Input your Email",
Validate: emailValidations,
}
}
编写简单的断言测试以验证我们是否创建了正确的结构。
唯一没有测试的行将是setEmail(getRunner())
但它很简单,可以被其他类型的测试覆盖。
无论出于何种原因,他们不会导出他们的stdin
界面( https://github.com/manifoldco/promptui/blob/master/prompt.go#L49 ),所以你不能嘲笑它,但你可以直接嘲笑os.Stdin
并预先os.Stdin
测试所需的一切。 虽然我同意@Adrian,但它有自己的测试,所以这不应该是必要的。
从源中提取和重构/简化: 填写os.Stdin以获取从中读取的函数
以这种方式重构,它可以用于从os.Stdin
读取并期望特定字符串的任何函数。
游乐场链接: https : //play.golang.org/p/rjgcGIaftBK
func TestSetEmail(t *testing.T) {
if err := TestExpectedStdinFunc("email@test.com", setEmail); err != nil {
t.Error(err)
return
}
fmt.Println("success")
}
func TestExpectedStdinFunc(expected string, f func() string) error {
content := []byte(expected)
tmpfile, err := ioutil.TempFile("", "example")
if err != nil {
return err
}
defer os.Remove(tmpfile.Name()) // clean up
if _, err := tmpfile.Write(content); err != nil {
return err
}
if _, err := tmpfile.Seek(0, 0); err != nil {
return err
}
oldStdin := os.Stdin
defer func() { os.Stdin = oldStdin }() // Restore original Stdin
os.Stdin = tmpfile
actual := f()
if actual != expected {
return errors.New(fmt.Sprintf("test failed, exptected: %s actual: %s", expected, actual))
}
if err := tmpfile.Close(); err != nil {
return err
}
return nil
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.