如何在不使用依赖注入的情况下从另一个包模拟函数?

per*_*nce 12 testing unit-testing go

有点像golang初学者,但之前我曾经使用过测试框架.如何在不注入依赖项的情况下嘲笑和伪造依赖方法返回的内容?我不想使用依赖注入的原因是因为正在使用许多外部包方法,并且在构造函数中注入所有方法都很笨重.

我搜索了这个在线/ stackoverflow,解决方案是始终使用依赖注入.有时这不是一个可行的选择.

这是我正在尝试以代码方式执行的操作:

B/b_test.go

package b

func TestResults(t *testing.T) {
    t.Run("Test", func(t *testing.T) {
        b := NewB()
        // How do I mock out and fake a.DoSomething() to be
        // "complete" instead of whats in the code right now?
        result = b.Results()
        assert.Equal(t, "complete", result)            
    }
}
Run Code Online (Sandbox Code Playgroud)

B/b.go

package b

import "a"

type B struct {}

func NewB() B {
    return &B{}
}

func (b B) Results() {
    return a.DoSomething()
}
Run Code Online (Sandbox Code Playgroud)

A/a.go

package a

func DoSomething() {
    return "done"
}
Run Code Online (Sandbox Code Playgroud)

谢谢!

Uve*_*tel 7

您可以将条件编译与构建标记一起使用

A/a.go

// +build !mock

package a
func DoSomething() {
    return "done"
}
Run Code Online (Sandbox Code Playgroud)

A/a_mock.go

// +build mock

package a
func DoSomething() {  // Insert fake implementation here
    return "complete"
}
Run Code Online (Sandbox Code Playgroud)

$ go test -tags mock


Yex*_*exo 6

一种方法是使用您要调用的函数创建一个变量,因此在 b/b.go 中包含以下内容:

var doSomething = a.DoSomething
func (b B) Results() {
    return doSomething()
}
Run Code Online (Sandbox Code Playgroud)

现在在 b_test.go 中你可以这样做:

func TestPrintResults(t *testing.T) {
        origDoSomething := doSomething
        defer func() { doSomething = origDoSomething }
        doSomething = func() {
          // Insert fake implementation here
        }
        b := NewB()

        result = b.Results()

        assert.Equal(t, "complete", result)            
}
Run Code Online (Sandbox Code Playgroud)