首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何在Go中测试os.exit场景

如何在Go中测试os.exit场景
EN

Stack Overflow用户
提问于 2014-10-07 05:56:48
回答 4查看 21.9K关注 0票数 41

给定以下代码

func doomed() {
  os.Exit(1)
}

如何正确测试调用此函数是否会导致使用go test退出?这需要在一组测试中发生,换句话说,os.Exit()调用不会影响其他测试,应该被捕获。

EN

回答 4

Stack Overflow用户

发布于 2015-10-29 09:24:52

有一个Andrew Gerrand的presentation ( Go团队的核心成员之一),他展示了如何做到这一点。

给定一个函数(在main.go中)

package main

import (
    "fmt"
    "os"
)

func Crasher() {
    fmt.Println("Going down in flames!")
    os.Exit(1)
}

下面是测试它的方法(通过main_test.go):

package main

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

func TestCrasher(t *testing.T) {
    if os.Getenv("BE_CRASHER") == "1" {
        Crasher()
        return
    }
    cmd := exec.Command(os.Args[0], "-test.run=TestCrasher")
    cmd.Env = append(os.Environ(), "BE_CRASHER=1")
    err := cmd.Run()
    if e, ok := err.(*exec.ExitError); ok && !e.Success() {
        return
    }
    t.Fatalf("process ran with err %v, want exit status 1", err)
}

代码所做的是通过exec.Command在单独的进程中再次调用go test,将执行限制为TestCrasher测试(通过-test.run=TestCrasher开关)。它还通过环境变量(BE_CRASHER=1)传入一个标志,第二次调用将检查该标志,如果设置了该标志,则调用被测系统,然后立即返回以防止进入无限循环。因此,我们被放回原来的调用点,现在可以验证实际的退出代码。

来源:安德鲁演示文稿的Slide 23。第二张幻灯片也包含指向presentation's video的链接。他谈到了47:09的子过程测试

票数 57
EN

Stack Overflow用户

发布于 2017-07-29 02:17:22

我通过使用bouk/monkey来实现这一点

func TestDoomed(t *testing.T) {
  fakeExit := func(int) {
    panic("os.Exit called")      
  }
  patch := monkey.Patch(os.Exit, fakeExit)
  defer patch.Unpatch()
  assert.PanicsWithValue(t, "os.Exit called", doomed, "os.Exit was not called")
}

当涉及到这类工作,以及故障注入和其他困难任务时,monkey是超级强大的。它确实来自with some caveats

票数 12
EN

Stack Overflow用户

发布于 2014-10-07 05:59:36

不能,您必须使用exec.Command并测试返回值。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26225513

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档