用mock测试我在golang中的接口,特别是测试一个调用兄弟函数的函数

bweufnob  于 2023-02-20  发布在  Go
关注(0)|答案(1)|浏览(134)

假设我有这段代码,我想为Foo()创建一个测试
重要的是
打电话给酒吧

package main

type MyInterface interface {
    Foo() error
    Bar() error
}

type MyStruct struct {
}

func NewMyStruct() MyInterface{
    return &MyStruct{}
}

func (m *MyStruct) Foo() error {
    // do something
    m.Bar()
    // do something else
    return nil
}

func (m *MyStruct) Bar() error {
    // do something
    return nil
}

有没有可能为此创建一个测试,让我在运行Foo之前模拟Bar的行为?或者我做了一些根本错误的事情?
我可以看到,如果我提取酒吧到自己的服务,我会嘲笑它的方式,但这也感觉不对。
任何见解或文档链接都是很好的。

agxfikkp

agxfikkp1#

您应该能够通过一些更改来实现您所需要的。首先,让我展示代码,然后我将带您完成所有相关的更改。

main.go文件

package main

type MyInterface interface {
    Foo() error
    Bar() error
}

type MyStruct struct {
    DS MyInterface
}

// here you've to depend upon an interface and return a pointer to a struct
func NewMyStruct(ds MyInterface) *MyStruct {
    return &MyStruct{
        DS: ds,
    }
}

func (m *MyStruct) Foo() error {
    // do something
    m.DS.Bar()
    // do something else
    return nil
}

func (m *MyStruct) Bar() error {
    // do something
    return nil
}

func main() {}

在这里,为了能够成功地模拟我们的依赖关系,我做了一些修改。让我来回顾一下:

  1. MyStruct具有类型为MyInterface的依赖项
    1.函数NewMyStruct接受接口作为参数,并返回指向MyStruct结构的指针
    1.在Foo方法中,我们将依赖指针接收器类型示例的DS字段
    现在,让我们切换到测试文件。

main_test.go文件

package main

import (
    "testing"

    "github.com/stretchr/testify/assert"
    "github.com/stretchr/testify/mock"
)

// 1. declare mock
type myStructMock struct {
    mock.Mock
}

// 2. implement the interface
func (m *myStructMock) Foo() error {
    args := m.Called()
    return args.Error(0)
}

func (m *myStructMock) Bar() error {
    args := m.Called()
    return args.Error(0)
}

func TestFoo(t *testing.T) {
    // 3. instantiate/setup mock
    myStructMock := new(myStructMock)
    myStructMock.On("Bar").Return(nil).Times(1)

    sut := NewMyStruct(myStructMock)
    err := sut.Foo()

    // 4. check that all expectations were met on the mock
    assert.Nil(t, err)
    assert.True(t, myStructMock.AssertExpectations(t))
}

在这里,我发现最好在代码中添加注解,以给予发生的事情的时间顺序。其思想是测试的真实的系统(例如sut变量)依赖于mock而不是实际实现。由于方法Times,我们确保Bar方法被调用一次。
当涉及到测试生产代码时,我总是使用这种方法,我发现它非常灵活和令人惊讶!
让我知道如果这对你有帮助或者你还需要别的东西,谢谢!

相关问题