duannian4784 2018-12-08 22:10
浏览 50
已采纳

如何正确测试依赖项

In Go, how would I test that a mock dependency has been called in the correct way.

If I have a struct that takes a interface for a dependency, after injection I want to be able to test the original mock object has been called.

My current code in this example I can not see that the struct value has changed. If I change my code to pass by reference it triggers the error:

s.simpleInterface.Call undefined (type *SimpleInterface is pointer to interface, not interface)

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条回答 默认 最新

  • dpp78272 2018-12-09 03:24
    关注

    I see three easy ways to fix this:

    1- Change the signature of the Call method to receive a pointer to MockSimple, and when instantiating the Simple struct, give it the address of your 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- Not the cleanest solution, but still works. Use it if you really cant use #1. Declare "hasBeenCalled" somewhere else and change your MockSimple to hold a pointer to it:

    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- Probably a really bad solution: using globals, so I would only use it as a last resort (always avoid global state). Make "hasBeenCalled" a global and modify it from the method.

    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")
        }
    }
    

    Cheers!

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥30 线性代数的问题,我真的忘了线代的知识了
  • ¥15 有谁能够把华为matebook e 高通骁龙850刷成安卓系统,或者安装安卓系统
  • ¥188 需要修改一个工具,懂得汇编的人来。
  • ¥15 livecharts wpf piechart 属性
  • ¥20 数学建模,尽量用matlab回答,论文格式
  • ¥15 昨天挂载了一下u盘,然后拔了
  • ¥30 win from 窗口最大最小化,控件放大缩小,闪烁问题
  • ¥20 易康econgnition精度验证
  • ¥15 msix packaging tool打包问题
  • ¥28 微信小程序开发页面布局没问题,真机调试的时候页面布局就乱了