代码之家  ›  专栏  ›  技术社区  ›  Charles Bryant

如何正确调用测试依赖项

  •  0
  • Charles Bryant  · 技术社区  · 6 年前

    在go中,我如何测试是否以正确的方式调用了模拟依赖项。

    如果我有一个结构接受依赖项的接口,那么在注入之后,我希望能够测试调用的原始模拟对象。

    在这个示例中,我当前的代码看不到结构值已更改。如果我将代码更改为按引用传递,它将触发错误:

    s.simpleInterface.call未定义(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 回复  |  直到 6 年前
        1
  •  3
  •   hscasn    6 年前

    我看到了三种简单的解决方法:

    1-更改call方法的签名以接收指向mock simple的指针,并在实例化简单结构时,将mock simple的地址提供给它:

    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 -可能是 非常糟糕的解决方案 :使用全局,所以我只能将其用作最后的手段(始终避免全局状态)。将“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")
        }
    }
    

    干杯!