首页 文章

如何测试依赖关系已被正确调用

提问于
浏览
0

在Go中,我将如何测试以正确方式调用模拟依赖项 .

如果我有一个结构接受依赖的接口,注入后我希望能够测试原始模拟对象已被调用 .

我在此示例中的当前代码我看不到struct值已更改 . 如果我更改我的代码以通过引用传递它会触发错误:

s.simpleInterface.Call undefined(type * SimpleInterface是指向接口的指针,而不是接口)

type SimpleInterface interface {
    Call()
}

type Simple struct {
    simpleInterface SimpleInterface
}

func (s Simple) CallInterface() {
    s.simpleInterface.Call()
}

type MockSimple struct {
    hasBeenCalled bool
}

func (ms MockSimple) Call() {
    ms.hasBeenCalled = true
}

func TestMockCalled(t *testing.T) {
    ms := MockSimple{}
    s := Simple{
        simpleInterface: ms,
    }
    s.CallInterface()

    if ms.hasBeenCalled != true {
        t.Error("Interface has not been called")
    }
}

1 回答

  • 3

    我看到三种简单的方法来解决这个问题:

    1-更改Call方法的签名以接收指向MockSimple的指针,并在实例化Simple结构时,为其指定mock的地址:

    func (ms *MockSimple) Call() {
        ms.hasBeenCalled = true
    }
    
    func TestMockCalled(t *testing.T) {
        ms := MockSimple{}
        s := Simple{
            simpleInterface: &ms,
        }
        s.CallInterface()
    
        if ms.hasBeenCalled != true {
            t.Error("Interface has not been called")
        }
    }
    

    2-不是最干净的解决方案,但仍然有效 . 如果你真的不能使用#1,请使用它 . 在其他地方声明“hasBeenCalled”并更改您的MockSimple以保存指向它的指针:

    type MockSimple struct {
        hasBeenCalled *bool
    }
    
    func (ms MockSimple) Call() {
        *ms.hasBeenCalled = true
    }
    
    func TestMockCalled(t *testing.T) {
        hasBeenCalled := false
        ms := MockSimple{&hasBeenCalled}
        s := Simple{
            simpleInterface: ms,
        }
        s.CallInterface()
    
        if hasBeenCalled != true {
            t.Error("Interface has not been called")
        }
    }
    

    3-可能是 really bad solution :使用全局变量,所以我只会将它作为最后的手段(总是避免全局状态) . 使"hasBeenCalled"成为全局变量并从方法中进行修改 .

    var hasBeenCalled bool
    
    type MockSimple struct{}
    
    func (ms MockSimple) Call() {
        hasBeenCalled = true
    }
    
    func TestMockCalled(t *testing.T) {
        ms := MockSimple{}
        s := Simple{
            simpleInterface: ms,
        }
        s.CallInterface()
    
        if hasBeenCalled != true {
            t.Error("Interface has not been called")
        }
    }
    

    干杯!

相关问题