如何在 Go 语言中模拟 exec.Command 进行多个单元测试?

2024-01-09

我刚刚学习了使用的单元测试函数exec.Command()即嘲笑exec.Command()。我继续添加更多单元案例,但遇到了无法模拟不同场景输出的问题。

这是示例代码hello.go我正在尝试测试...

package main

import (
    "fmt"
    "os/exec"
)

var execCommand = exec.Command

func printDate() ([]byte, error) {
    cmd := execCommand("date")
    out, err := cmd.CombinedOutput()
    return out, err
}

func main() {
    fmt.Printf("hello, world\n")
    fmt.Println(printDate())
}

下面是测试代码hello_test.go...

package main

import (
    "fmt"
    "os"
    "os/exec"
    "testing"
)

var mockedExitStatus = 1
var mockedDate = "Sun Aug 20"
var expDate = "Sun Aug 20"

func fakeExecCommand(command string, args ...string) *exec.Cmd {
    cs := []string{"-test.run=TestHelperProcess", "--", command}
    cs = append(cs, args...)
    cmd := exec.Command(os.Args[0], cs...)
    cmd.Env = []string{"GO_WANT_HELPER_PROCESS=1"}
    return cmd
}

func TestHelperProcess(t *testing.T) {
    if os.Getenv("GO_WANT_HELPER_PROCESS") != "1" {
        return
    }

    // println("Mocked Data:", mockedDate)
    fmt.Fprintf(os.Stdout, mockedDate)
    os.Exit(mockedExitStatus)
}

func TestPrintDate(t *testing.T) {
    execCommand = fakeExecCommand
    defer func() { execCommand = exec.Command }()

    out, err := printDate()
    print("Std out: ", string(out))
    if err != nil {
        t.Errorf("Expected nil error, got %#v", err)
    }
    if string(out) != expDate {
        t.Errorf("Expected %q, got %q", expDate, string(out))
    }
}

func TestPrintDateUnableToRunError(t *testing.T) {
    execCommand = fakeExecCommand
    defer func() { execCommand = exec.Command }()

    mockedExitStatus = 1
    mockedDate = "Unable to run date command"
    expDate = "Unable to run date command"

    out, err := printDate()
    print("Std out: ", string(out))
    if err != nil {
        t.Errorf("Expected nil error, got %#v", err)
    }
    if string(out) != expDate {
        t.Errorf("Expected %q, got %q", expDate, string(out))
    }
}

go test第二次测试失败TestPrintDateUnableToRunError...

$ go test hello
Std out: Sun Aug 20Std out: Sun Aug 20--- FAIL: TestPrintDateTomorrow (0.01s)
    hello_test.go:62: Expected "Unable to run date command", got "Sun Aug 20"
FAIL
FAIL    hello   0.017s

尽管我正在尝试设置全局mockedDate测试用例内的值,它仍然获取初始化时使用的全局值。全局值没有设置吗?或者对该全局变量的更改没有得到更新TestHelperProcess?


我得到了这个问题的解决方案...

全局值没有设置吗?或者对该全局变量的更改没有在 TestHelperProcess 中更新?

自从在TestPrintDate(), fakeExecCommand被调用而不是 exec.Command,并且调用fakeExecCommand runs go test仅运行TestHelperProcess(),这完全是一个新的调用,其中仅TestHelperProcess()将被执行。由于仅TestHelperProcess()被调用时,全局变量未被设置。

解决方案是将 Env 设置为fakeExecCommand,并将其检索到TestHelperProcess()并返回这些值。

PS> TestHelperProcess被重命名为TestExecCommandHelper,并且很少有变量被重命名。

package main

import (
    "fmt"
    "os"
    "os/exec"
    "strconv"
    "testing"
)

var mockedExitStatus = 0
var mockedStdout string

func fakeExecCommand(command string, args ...string) *exec.Cmd {
    cs := []string{"-test.run=TestExecCommandHelper", "--", command}
    cs = append(cs, args...)
    cmd := exec.Command(os.Args[0], cs...)
    es := strconv.Itoa(mockedExitStatus)
    cmd.Env = []string{"GO_WANT_HELPER_PROCESS=1",
        "STDOUT=" + mockedStdout,
        "EXIT_STATUS=" + es}
    return cmd
}

func TestExecCommandHelper(t *testing.T) {
    if os.Getenv("GO_WANT_HELPER_PROCESS") != "1" {
        return
    }

    // println("Mocked stdout:", os.Getenv("STDOUT"))
    fmt.Fprintf(os.Stdout, os.Getenv("STDOUT"))
    i, _ := strconv.Atoi(os.Getenv("EXIT_STATUS"))
    os.Exit(i)
}

func TestPrintDate(t *testing.T) {
    mockedExitStatus = 1
    mockedStdout = "Sun Aug 201"
    execCommand = fakeExecCommand
    defer func() { execCommand = exec.Command }()
    expDate := "Sun Aug 20"

    out, _ := printDate()
    if string(out) != expDate {
        t.Errorf("Expected %q, got %q", expDate, string(out))
    }
}

func TestPrintDateUnableToRunError(t *testing.T) {
    mockedExitStatus = 1
    mockedStdout = "Unable to run date command"
    execCommand = fakeExecCommand
    defer func() { execCommand = exec.Command }()

    expDate := "Unable to run date command"

    out, _ := printDate()
    // println("Stdout: ", string(out))
    if string(out) != expDate {
        t.Errorf("Expected %q, got %q", expDate, string(out))
    }
}

go test结果如下... (故意让一项测试失败以表明模拟工作正常)。

 go test hello
--- FAIL: TestPrintDate (0.01s)
        hello_test.go:45: Expected "Sun Aug 20", got "Sun Aug 201"
FAIL
FAIL    hello   0.018s
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 Go 语言中模拟 exec.Command 进行多个单元测试? 的相关文章

  • Python:如何模拟kafka主题进行单元测试?

    我们有一个消息调度程序 它会根据消息属性生成一个哈希键 然后将其与该键一起放入 Kafka 主题队列中 这样做是为了重复数据删除的目的 但是 我不确定如何在不实际设置本地集群并检查其是否按预期执行的情况下测试此重复数据删除 在线搜索用于模拟
  • 非本地包中的本地导入

    我知道应该避免本地进口 但在这种情况下有特殊情况需要 这是一个私人仓库 heroku buildpack 在go get 由于服务器上缺少私钥 与绝对 URL 一起使用时会出现此阶段 现在我得到这个错误local import in non
  • 解组此 xml 时遇到问题

    尝试了解如何在 Go 中解组 XML 通读多个示例和 stackoverflow 问题 我想要的是一个包含系统上安装的所有补丁的切片 我什至无法解组补丁 没有错误 只是一个空切片 可能做的事情基本上是错误的 提前感谢您的任何建议
  • React - Jest - 测试阻止默认操作

    我不知道如何测试按键事件并防止默认 测试达到了代码但是preventDefault从未被称为 Received number of calls 0 反应组件 App js const onKeyDown e gt console log T
  • 如何在控制器中模拟 Automapper (IMapper)

    我正在尝试为现有的 MVC Web 应用程序编写单元测试 我在自动映射器中面临一些问题 IMapper 每当使用地图函数时它都会返回null value 我的控制器代码 public class UserAdministrationCont
  • 如何在Python Idle中运行单元测试?

    我为我的单词出现 Gui 项目创建了一个 python 单元测试 我想测试前 5 个单词的出现情况 因此它应该返回一个真值 但是我不知道如何运行单元测试 我正在尝试使用空闲 shell 但我应该使用 Visual Studio 命令提示符
  • MOQ 更改字段值的模拟 void 方法

    我是最小起订量和模拟的新手 假设我有一个像这样的类 带有一个更改值的 void 方法 public class Sample public virtual int Number get set public virtual void Che
  • go语言读取并合并两个Yaml文件

    假设我们有两个 yaml 文件 master yaml someProperty someVaue anotherProperty anotherValue 覆盖 yaml someProperty overriddenVaue 是否可以解
  • 使用 rhino 模拟进行 lambda 单元测试失败

    如果我有这个测试 Expect Call session Single
  • VS2010和ASP.NET单元测试问题/WebHostAdapter异常

    我花了半天的时间试图让 ASP NET 单元测试正常工作 如艾伦的开发博客 http www gangleri net 2007 12 29 UnitTestingASPNetApplicationsWithVisualStudio2008
  • 如何从 gorm 中的模型获取表名?

    是否可以获得模型的表名 我发现可以从模型结构但我不知道如何正确地做到这一点 我没有找到该结构的任何初始化 user User tableName db 对于 Gorm v2 根据https github com go gorm gorm i
  • Visual Studio 中的测试单独成功,但一组失败

    当我在 Visual Studio 中单独运行测试时 它们都顺利通过 然而 当我同时运行所有这些时 有些通过 有些失败 我尝试在每个测试方法之间暂停 1 秒 但没有成功 有任何想法吗 在此先感谢您的帮助 你们可能有一些共享数据 检查正在使用
  • 无法在 Mac M1 上使用 VSCode 运行调试 Go

    我发现一个遇到同样问题的主题 无法在vscode apple m1中调试Golang https stackoverflow com questions 67637872 cant debug golang in vscode apple
  • 如何在 ASP.net core 中为自定义模型绑定器编写单元测试

    我已经为属性编写了自定义模型绑定器 现在我正在尝试编写相同的单元测试 但无法为模型绑定器创建对象 谁能帮我 下面是我必须编写测试的代码 public class JourneyTypesModelBinder IModelBinder pu
  • 如何分发 Go 应用?

    我用 Go 编写了一个应用程序 它有两个外部依赖项需要在编译之前满足 在 Go 生态系统中 打包此应用程序以实现简单安装过程 包括安装这些远程依赖项 的最佳方法是什么 用户将如何安装我的应用程序 如果您期望用户编译您的应用程序 并且该应用程
  • 如何使用 EntityType 字段对 Symfony 4 表单进行单元测试

    如何使用 EntityType 字段对 Symfony 4 表单进行单元测试 当我运行测试时 vendor bin simple php单元测试 Unit Form ProductFormTest php 这是我的终端中的输出 PHPUni
  • 如何测试与 ModelState 一起使用的 ActionFilterAttribute?

    正如卡齐 曼祖尔 拉希德 Kazi Manzur Ra shid 以及其他人 在这篇博文 http weblogs asp net rashid archive 2009 04 01 asp net mvc best practices p
  • 指向切片和数组的指针

    我正在查看 Go 的堆包 https golang org pkg container heap https golang org pkg container heap 优先队列示例并遇到了这个 type PriorityQueue Ite
  • MockMVC 给出 HttpMessageNotReadableException

    我仍在学习测试方法 并且正在尝试让 MockMvc 测试为我工作 这是一个简单的 REST 控制器 此时仅使用帖子中的 json 信息进行一些身份验证 我实际上已经实现了代码 所以我知道它正在工作 因为我收到了带有正确输入的正确响应和我放在
  • Run As JUnit 未出现在 Eclipse 中 - 使用 JUnit4

    我正在尝试为我的 Web 应用程序编写 JUnit4 测试 它们之前一直工作正常 但是 现在当我尝试通过右键单击类文件 gt Run As gt JUnit Test 来运行测试时 我看不到该选项 我认为这可能是因为一位同事意外提交了一些

随机推荐

  • Bootstrap 为列添加边距

    这可能很简单 但我的思绪却纠结于如何解决这个问题 花了一个小时左右搜索这个 但仍然不起作用 我的 HTML 代码 div class section container light bg div class container div cl
  • .NET Core 中的 AES-256-CBC (C#)

    我正在搜索 C 代码来重现以下 openssl 命令 openssl enc d aes 256 cbc in my encrypted file csv enc out my decrypted file csv pass file ke
  • 为什么我的 git 没有从 1.7.1 更新到 1.9.4

    我在REDHAT 6上 我想更新我的git 我尝试了多种方法 第一种方法 yum 更新 git 我得到 没有标记为更新的软件包 第二种方法 wget http git core googlecode com files git 1 8 3
  • 如何在android中关闭AlertDialog

    我创建了包含 4 个按钮的 AlertDialog OptionDialog new AlertDialog Builder this OptionDialog setTitle Options LayoutInflater li Layo
  • 数据库安全的日期/时间字符串?

    哪种格式的日期 时间字符串被认为是跨平台 跨数据库 通用安全的 这会吗YYYY MMM DD HH MM SS在 MySQL SQLite 2 3 MsSQL 和其他常见数据库中使用是否被认为是安全的 怎么样2010 Jul 12 12 0
  • 通用哈希函数系列只是为了防止敌人攻击吗?

    如果我的目的只是拥有一个好的哈希函数 将数据均匀地分布到所有存储桶中 那么我不需要想出一系列哈希函数 我只需使用一个好的哈希函数即可 对吗 拥有一系列哈希函数的目的只是让敌人更难构建病态数据集 因为当我们随机选择哈希函数时 他 她不知道使用
  • 创建梯度并返回方法

    抱歉 关于 iPhone 和 Quartz 编程的新手问题 刚刚开始从 C 到 Objective C 的转换 所以 我有这样一个类方法 CGGradientRef CreateGradient UIColor startColor end
  • 在映射内缩进 YAML 序列

    以下内容应该有效吗 parent child child 所以我们拥有的是映射内的一系列值 具体问题是第二行和第三行的缩进是否有效 Ruby YAML dump 生成了此代码 但是 Yaml 解析器here http www codepro
  • TFS 2010 中 witadmin 操作的日志在哪里?

    从 Visual Studio 2010 命令行运行 witadmin 命令时 此操作记录在 TFS 2010 中的何处 一个示例命令是 C gt witadmin exportwitd collection http server 808
  • 如何在 Dart 中返回不可变列表?

    所以在其他语言中有ArrayList or MutableList它允许修改 添加 删除 删除 列表项 现在为了避免修改这些列表 只需返回MutableList or ArrayList as a List 我想做同样的事情Dart 但在D
  • 如何在 Objective C 中使用 strlen 查找字符串长度

    我有一个字符串存储在字符串变量中 我想查找 str 变量中可用的字符串长度 我尝试过 strlen str 它不工作 如果您的字符串是 C 字符串 那么您可以使用strlen str 如果它是一个NSString str 那么你可以使用NS
  • 使用默认值而不是异常来提升 numeric_cast<> ?

    每当升压时numeric cast lt gt 转换失败 会抛出异常 boost 中是否有类似的模板可以让我指定默认值 或者在这种情况下捕获异常是我唯一能做的事情 我不太担心所有额外异常处理的性能 但我宁愿使用标准模板也不愿编写无用的包装函
  • 找不到 PROTOBUF 编译器

    我正在尝试使用 Caffe 进行 CMake 但我的系统找不到 protobuf 编译器 我之前安装过protobuf2 7 0 现在我切换回2 6 1 如何配置我的 CMake 来识别 protobuf2 6 1 编译器 我已经做好了 s
  • C++ 中正弦、余弦和平方根的最快实现(不需要太精确)

    我在过去一个小时内搜索了这个问题 但只有泰勒级数或一些示例代码要么太慢要么根本无法编译 好吧 我在谷歌上找到的大多数答案都是 谷歌一下 已经有人问过了 但遗憾的是it s not 我在低端 Pentium 4 上分析我的游戏 发现大约 85
  • 如何关闭对话框内的 jQuery Dialog?

    如何在不使用关闭按钮的情况下关闭对话框内的 jQuery 对话框 对话框内是一个简单的表单请求 如果提交成功 UI 对话框将自动关闭并刷新父页面 div div
  • 如何在一个类中执行多个 setTimeout jQuery?

    我有一堂课叫 content 该内容有一个名为 data time 我想隐藏它所在的所有元素 content与 一起上课setTimeout 功能 有人可以帮助我吗 HTML 代码 div class content first div d
  • Amazon Web Services (AWS) Cognito 错误“令牌不是来自此身份池支持的提供商。”

    我在跑步这个应用程序来自 GitHub https github com aws samples aws cognito java desktop app它允许用户注册并登录 Cognito 客户端应用程序 我正在使用适用于企业 Java
  • Web SQL DROP/DELETE 表不起作用

    我尝试了几种不同的命令来清除我的 Web SQL 数据库 但没有一个起作用 只是为了向您展示我已将所有这些功能组装成一个过度的功能 我缺少什么 Drop Table from Database Fix This function overK
  • 定义很多常量会导致性能或内存问题吗?

    我有一个网站 它使用了很多常量 这些常量的定义如下 例如 define CONSTANT 1 我目前有大约 200 个这样的定义的列表 每次加载页面时都会运行此列表 这会严重影响我的性能或内存使用吗 有理由避免在每次页面加载时列出 200
  • 如何在 Go 语言中模拟 exec.Command 进行多个单元测试?

    我刚刚学习了使用的单元测试函数exec Command 即嘲笑exec Command 我继续添加更多单元案例 但遇到了无法模拟不同场景输出的问题 这是示例代码hello go我正在尝试测试 package main import fmt