如何仅在测试时允许一个包访问另一个包的未导出数据?

2024-05-19

In Go 编程语言,第 11.2.4 节,有一个外部测试访问的示例fmt.isSpace()通过声明IsSpace in fmt's export_test.go文件。这似乎是完美的解决方案,所以这就是我所做的:

a/a.go:

package a

var x int

func Set(v int) {
    x = v
}

a/a_test.go:

package a
import "testing"

func TestSet(t *testing.T) {
    Set(42)
    if x != 42 {
        t.Errorf("x == %d (expected 42)", x)
    }
}

func Get() int {
    return x
}

(跑步go test in a/工作正常。)

b/b.go:

package b
import "path/to/a"

func CallSet() {
    a.Set(105)
}

b/b_test.go

package b
import (
    "testing"
    "path/to/a"
)

func TestCallSet(t *testing.T) {
    CallSet()
    if r := a.Get(); r != 105 {
        t.Errorf("Get() == %d (expected 105)", r)
    }
}

不幸的是,当我跑步时go test in b/, I get:

./b_test.go:11: undefined: a.Get

尝试同时运行两组测试go test ./...没有帮助。

经过一番仔细研究后,我发现“*_test.go 文件被编译到包中仅当对该包运行 go test 时 https://github.com/golang/go/issues/10184“(强调我的)。(所以,换句话说,我可以访问a.Get从一个a_test外部测试包中a/,但不是来自外部的任何包a/.)

是否有其他方法可以允许一个包中的测试访问另一个包中的其他内部数据,以进行集成测试?


如前所述,没有任何方法可以“授予”对未导出标识符的访问权限。

关于的一些澄清fmt不过,包的测试是必要的/合理的。

有2种测试:黑盒子测试和白盒测试。

黑盒子测试是指您将包视为“黑盒”,并且仅通过其导出的标识符(通过其“公共 API”,其他包看到的)对其进行测试。在这种情况下,测试文件具有不同的包名称(例如fmt_test当测试时fmt包裹)。

白盒测试是指使用包的导出和未导出标识符。要创建白盒测试,请在测试文件中指定与正在测试的包相同的包名称(因此,fmt如果出现以下情况fmt包测试)。

标准库中包含的测试fmt包裹intend成为黑盒测试,但这样就无法测试所有内容。所以 Go 的作者们尝试了mixed版本:他们包括一个单一的export_test.go使用相同包声明的测试文件(package fmt)因此它可以访问未导出的标识符fmt包,并且它“导出”2个标识符,以便其他(黑盒)测试文件可以访问:

var IsSpace = isSpace
var Parsenum = parsenum

The authors did so because they wanted to minimize the use of unexported identifiers, and so this explicitly marks what unexported identifiers are used, and basically acts as a "bridge" between the fmt package and the black-box tests of the fmt package.

这里要注意的一件事是,这些只会“导出”到fmt封装(以及白盒测试fmt当然),并且不适用于其他包或其他包的测试。原因很简单,因为测试文件在构建包时不会被解析和编译,只有在运行包测试时才会被解析和编译。

解决方案?

未导出的标识符用于包本身,与其他人无关。这意味着没有其他包应该想要测试它们。如果需要测试它们,则必须在包自己的测试中完成。

如果对于集成测试,您需要访问未导出的标识符,则包必须导出“某些内容”,该内容要么公开值(或其某些部分),要么在不导出敏感数据或实现细节的情况下帮助测试。如果包 API 设计良好且测试彻底,则永远(很少)不需要这样做。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何仅在测试时允许一个包访问另一个包的未导出数据? 的相关文章

  • 如何集成测试Azure Web Jobs?

    我有一个 ASP NET Web API 应用程序 支持 Azure Web 作业 其功能由 API 控制器添加到存储队列的消息触发 使用 OWIN 测试 Web API 非常简单 但如何测试 Web 作业呢 我是否在测试运行器的内存中运行
  • 优化 golang 中的数据结构/字对齐填充

    与我在 C 中学到的类似 我相信填充导致了两个结构体实例大小的差异 type Foo struct w byte 1 byte x byte 1 byte y uint64 8 bytes type Bar struct x byte 1
  • Go API 在 html 中显示 swagger api 规范 (json) (Swagger UI)

    我有一个服务于特定端口的应用程序 gorilla mux 我也有一个 json 文件形式的 swagger API 规范 是否有任何 go API 可以像 spring boot 一样从 JSON 文件生成 swagger UI 定义 我正
  • LocalDate 与属性占位符 Spring

    我正在使用 Spring Boot 和属性占位符 我有一个属性文件 其值为 date A 24 07 17 我有一堂课 我正在使用 Value注解 Value date A private LocalDate dateA 但我在运行时遇到运
  • Rspec——需要存根在另一个文件中调用的 File.open

    在我的测试中 我正在初始化一个名为的新类Package带有一些参数 在此类的初始化中 我打开一个在远程机器上可用的文件 但不是本地常见的文件 我想知道如何在测试中对该方法进行存根 我正在使用 rspec 和 mocha 我尝试过类似的东西
  • Golang - 更改 Windows 上的构建工作路径

    我正在使用 SublimeText3 GoSublime 插件 在 Windows 8 上测试简单的 Go 程序 go run v example go 在运行之前它正在内部编译 应用程序数据 本地 温度 目录 我的防病毒程序认为这是病毒并
  • GO并发编程测试

    我试图确保我的并发程序不存在以下情况 僵局 livelock 饥饿 我找到了以下工具http blog golang org race detector http blog golang org race detector 我尝试编译并运行
  • Python 模拟中的模拟属性?

    我使用起来相当困难mock在Python中 def method under test r requests post http localhost post print r ok prints
  • 按引用或按值扫描功能

    我有以下代码 statement SELECT id from source where mgmt 1 var exists string errUnique dr db QueryRow statement mgmt Scan exist
  • nsq 无法通过连接到 nsqlookupd 来消费消息

    我尝试使用 docker compose 来运行 nsq docker compose yml如下 version 3 services nsqlookupd image nsqio nsq command nsqlookupd ports
  • 在 Go 中使用电子邮件地址创建证书签名请求 (CSR)

    我尝试使用 crypto x509 包生成 CSR 但没有找到将 emailAddress 字段添加到其主题中的方法 根据文档证书申请 http golang org pkg crypto x509 CertificateRequest结构
  • 如何在RobotFramework中进行多行测试设置或拆卸而不创建新关键字?

    我需要在测试用例中调用两个拆卸关键字 但不能为此创建新关键字 我很有趣 如果有这样的关键字语法 例如文档或循环 Documentation line1 line2 line3 使用 运行关键词 http robotframework org
  • 使用覆盖率信息测试 Go 中的 os.Exit 场景 (coveralls.io/Goveralls)

    这个问题 如何在 Go 中测试 os exit 场景 https stackoverflow com questions 26225513 how to test os exit scenarios in go 以及其中得票最高的答案 列出
  • 重新插入通道导致死锁

    我有稳定的入站 作业 流 将其输入到无缓冲通道中 我有一个for range循环来迭代项目并处理它们 如果处理该项目失败 我会将项目重新插入通道中 以便稍后重试 问题是当我将项目重新插入通道时 它陷入僵局 我明白为什么会发生这种情况 处理器
  • (转)如何使用toml文件?

    正如标题 我想知道如何使用 golang 中的 toml 文件 在此之前 我展示了我的 toml 示例 这样对吗 datatitle enable true userids 12345 67890 datatitle 12345 prop1
  • Golang中如何获得100%的代码覆盖率? [复制]

    这个问题在这里已经有答案了 我无法获得 100 的代码覆盖率 因为我无法在 Golang 中测试 Fatals 我发现了一些问答 包括this one https stackoverflow com questions 30688554 h
  • Protractor e2e 测试表头和 , 标签

    我正在使用下表 我想测试每个标签 th td 标签 该标签中的文本以及该文本的计数 HTML 片段 table class table table striped tbody tr th b a Patient Id a b th th b
  • 根据值匹配数组

    我使用以下代码来解析 yaml 并应得到输出为runners对象和函数build应更改数据结构并根据以下结构提供输出 type Exec struct NameVal string Executer string 这是我尝试过的 但我不知道
  • 使用 Gorilla 会话自定义后端有什么优势?

    我想使用 Redis 进行会话管理 但我不明白使用 Redis 作为 Gorilla 会话包的自定义后端比直接使用它有什么优势 Gorilla 会话包的链接 http www gorillatoolkit org pkg sessions
  • benchmem 的输出

    使用内存分析器运行基准测试时 我看到以下输出 SomeFunc 100 17768876 ns op 111 B op 0 allocs op 我不明白输出 0 allocs op 但分配了 111 B 知道这意味着什么吗 我的函数是否在堆

随机推荐