【发布时间】:2017-08-07 22:45:45
【问题描述】:
我对 golang 还很陌生,我正在为一项简单的任务而苦苦挣扎。
我在 golang 中有以下课程
type struct A {
}
func (s *A) GetFirst() {
s.getSecond()
}
func (s *A) getSecond() {
// do something
}
我想为它写一些测试,但是我需要覆盖getSecond()。我尝试在我的测试文件中执行以下操作
type Ai interface {
getSecond()
}
type testA struct {
A
}
func (s *testA) getSecond() {
// do nothing
}
func TestA(t *testing.T) {
a := &A{}
t := &testA{A: a}
t.GetFirst()
}
这里的想法是将 A getSecond() 方法暴露给接口并通过使用嵌入来覆盖,但这似乎不起作用。测试仍然调用getSecond() 的原始实现,而不是我模拟的。
一种解决方案当然是为 A 创建一个包含getFirst() 和getSecond() 的适当接口,然后在测试中创建一个实现getFirst() 调用原始实现和getSecond() 一个假人的结构。我觉得这很麻烦,而且不是正确的做事方式。
另一种可能性是在实际实现中将getSecond() 分配给一个变量并在测试中覆盖该变量,但我也觉得这样做只是为了一个简单的覆盖有点奇怪。
我错了吗?有没有更简单的方法可以使用 golang 做到这一点?
【问题讨论】:
-
为什么要模拟这两种方法?真正的原因是什么?真正有效的是:构造一个
A(这很容易,因为您可以访问所有血腥的内部结构),然后检查getFirst()和getSecond()是否产生所需的结果。冲洗并重复。看看标准库是如何做到的。也许你还在受其他语言的影响,getFirst()使用了getSecond(),这让你相信你必须模拟getSecond()。不,您可以通过A的状态来控制getSecond()所做的事情。请注意:Go 中没有 getter(而不是 golang)。 -
实际上那些不是吸气剂,我只是选择像示例中那样命名这些函数:) 这里的问题是 getFirst 将调用 getSecond 执行在单元测试下不起作用的东西情况。
-
更准确地说。 A 有一个 baseUrl 并且 getFirst() 执行一个 http 请求,但是在此之前它需要根据请求的类型重写 url 基域以包含子域,这就是 getSecond() 所做的。这会导致 httptest 包出现问题,因为您最终会得到 subdomain.127.0.0.1
-
好吧,然后将 getFirst() 分成两部分
X()和Y()。Y部分是对 URL 执行 HTTP 请求的主要操作,该 URL 是Y(url *url.URL)的参数或A的字段。现在您可以测试整个“获取一些 URL 并对其进行处理”是否有效。X部分调用getSecond()并负责生成的 URL。getFirst()现在所做的只不过是将 X 和 Y 链接起来,也许将 Y 的输出填充到 X 中。如果 Y 工作正常(可测试)并且 X 工作(也可测试)你就完成了。 -
你说得对,它可以解决大部分问题,但是测试
getFirst()以防止某些未来的开发人员进入并添加测试未涵盖的逻辑呢?能够通过测试捕捉到这样的场景会很好
标签: unit-testing go interface overriding