首页 > 解决方案 > 如何对这个用 golang 编写的 promptui 包进行单元测试?

问题描述

我是 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
}

我想我需要以某种方式模拟标准输入,但无法在测试中找出最好的方法。

标签: unit-testinggocommand-prompt

解决方案


您不应该尝试测试promptui,因为它预计会由其作者进行测试。

你可以测试什么:

  1. 创建时发送正确的参数promptui.Prompt
  2. promptui.Prompt在代码中使用它
  3. 您正确处理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
}

您将需要单独的模拟来测试错误流。

更新您的代码以注入模拟:

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()),但它是微不足道的,可以被其他类型的测试覆盖。


推荐阅读