Golang:替换函数单元测试

huangapple go评论122阅读模式
英文:

Golang: Replace function unit testing

问题

我正在使用Golang进行工作,目前正在使用Testify进行一些有趣的单元测试,我的文件如下所示:

  1. type myStruct struct {
  2. field_1 string
  3. }
  4. func (self *myStruct) writeFirst() {
  5. //做一些事情
  6. //修改field_1
  7. self.writeSecond()
  8. }
  9. func (self *myStruct) writeSecond() {
  10. //做一些事情
  11. }

在这种情况下,我正在测试writeFirst(),但我想替换writeSecond(),因为它使用了我不想使用的涉及互联网的http内容。

我认为使用第二个结构体并将myStruct设置为匿名字段将是解决方案,但它不起作用,因为我的第二个结构体和myStruct具有不同的上下文。

在这种情况下,我不能使用模拟,因为writeSecond是结构体的一个方法。

我的测试用例如下所示:

  1. func TestWriteFirst(t *testing.T) {
  2. myStc := myStruct{}
  3. assert.Equal(t, "My response", myStc.field_1)
  4. }

我想要的只是测试writeFirst而不传递给writeSecond()。

英文:

I'm working with Golang, and currently I'm doing some fun unit test with Testify, my file look like this

  1. type myStruct struct {
  2. field_1 string
  3. }
  4. func (self *myStruct) writeFirst() {
  5. //doing something
  6. //modify field_1
  7. self.writeSecond()
  8. }
  9. func (self *myStruct) writeSecond() {
  10. //doing something
  11. }

In this case I'm testing writeFirst() but I'm trying to replace writeSecond() because it is using http stuff that I don't want to use because it access to internet.

I think that use a second struct and set myStruct as anonymous field will be the solution, but it's not working because me second struct and myStruct have a diferent context.

In this case I can't use mocks cause writeSecond is a method of the struct.

My test case looks like this:

  1. func TestWriteFirst(t *testing.T) {
  2. myStc := myStruct{}
  3. assert.Equal(t,"My response", myStc.field_1)
  4. }

All that I want is testing writeFirst without pass to writeSecond()

答案1

得分: 2

为了说明评论中提到的重构方式,你可以考虑只在一个实现了接口的实例上调用第二个函数:

  1. type F2er interface {
  2. Func2()
  3. }
  4. type S struct{ _f2 F2er }
  5. var s = &S{}
  6. func (s *S) f2() F2er {
  7. if s._f2 == nil {
  8. return s
  9. }
  10. return s._f2
  11. }
  12. func (s *S) Func1() {
  13. fmt.Println("s.Func1")
  14. s.f2().Func2()
  15. }

在这里,Func1s.f2() 上调用 Func2,而不是直接调用 s

  • 如果 s 中没有设置任何内容,s.f2() 返回... 它自己:s
  • 如果 s._f2 被任何其他实现了 Func2struct 替换,s.f2() 将返回该实例而不是自身。

在这个playground 脚本中可以看到一个完整的示例。

输出:

  1. TestFunc1
  2. s.Func1
  3. s.Func2
  4. TestFunc1bis
  5. s.Func1
  6. testS.Func2 <=== 不同的 Func2 调用
英文:

To illustrate the kind of refactoring mentioned by Not-a-Golfer in the comments, you could consider calling your second function only on an instance that is an interface:

  1. type F2er interface {
  2. Func2()
  3. }
  4. type S struct{ _f2 F2er }
  5. var s = &amp;S{}
  6. func (s *S) f2() F2er {
  7. if s._f2 == nil {
  8. return s
  9. }
  10. return s._f2
  11. }
  12. func (s *S) Func1() {
  13. fmt.Println(&quot;s.Func1&quot;)
  14. s.f2().Func2()
  15. }

Here: Func1 calls Func2 on s.f2(), not directly s.

  • If nothing has been set in s, s.f2() returns... itself: s
  • if s._f2 was replaced by any other struct which implements Func2, s.f2() returns that instance instead of itself.

See a complete example in this playground script.

Output:

  1. TestFunc1
  2. s.Func1
  3. s.Func2
  4. TestFunc1bis
  5. s.Func1
  6. testS.Func2 &lt;=== different Func2 call

huangapple
  • 本文由 发表于 2014年7月17日 05:25:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/24791040.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定