unit-testing - 我如何对这个用 golang 编写的 promptui 包进行单元测试?

标签 unit-testing go command-prompt

我是 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,因为它应该由其作者进行测试。

您可以测试的内容:

  1. 您在创建 promptui.Prompt 时发送了正确的参数
  2. 您在代码中使用了 promptui.Prompt
  3. 您正确处理了 promptui.Prompt 结果

如您所见,所有这些测试都不会验证 promptui.Prompt 是否在内部正常工作。

测试 #2 和 #3 可以合并。您需要针对 mock 运行您的代码,如果您得到正确的结果,您可以相信 #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
}

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

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

func setEmail(runner Runner) string {
    email, err := runner.Run()
    if err != nil {
      color.red("failed getting email")
      os.exit(3)
    }
    return email
}

现在可以测试了。

创建创建提示的函数:

func getRunner() promptui.Prompt {
  return promptui.Prompt{Label: "Input your Email",
     Validate: emailValidations,
  }
} 

编写简单的断言测试来验证我们是否创建了正确的结构。

唯一未测试的行是 setEmail(getRunner()) 但它很简单,可以被其他类型的测试覆盖。

关于unit-testing - 我如何对这个用 golang 编写的 promptui 包进行单元测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53306447/

相关文章:

java - assertEquals(obj,obj) 返回失败的测试

c - 使用 Check for C 单元测试时出现的问题

amazon-web-services - 使用 golang 的 AWS S3 并行下载

MySQL 插入 Float32 和 Float64 Go

powershell - 调用powershell.exe给出参数设置错误

mysql - 如何在 MySql 命令行中的表名之间包含空格?

c# - 如何使用 NSubstitute 模拟惰性类

java - Jacoco 显示错误的覆盖范围检查结果

pointers - 在 Go 中传递任意 slice

windows - "Access is denied"带 NUL > index.html 命令