去:使用嘲弄和
#编程 #go #unittest #mocktest

介绍

Go,也称为Golang,是一种由Google设计的编程语言,可简单,高效且可扩展。它被广泛用于开发Web应用程序,微服务和其他网络应用程序。在GO中,单位测试是开发过程的重要组成部分。但是,对依赖性组件进行测试可能具有挑战性。这是模拟测试发挥作用的地方。

模拟测试是一种用于模拟组件依赖性的技术,以测试不同方案下组件的行为。它允许开发人员隔离测试组件,而不必担心依赖关系。有各种可以在GO中进行模拟测试的工具,其中最受欢迎的工具是嘲弄。

嘲弄是一种代码生成工具,可为GO接口创建模拟对象。它可以为内部和外部软件包生成模拟,并支持各种测试框架,例如GO的内置测试包并作证。在本文中,我们将讨论如何使用嘲弄来生成模拟对象,以便通过使用tistify软件包进行测试。

安装

第一步是使用以下命令安装嘲弄:

go install github.com/vektra/mockery/v2@v2.20.0

这将安装最新版本的嘲讽及其依赖项。

有关安装的更多信息:https://vektra.github.io/mockery/installation/

阅读嘲弄文档:https://vektra.github.io/mockery/

如何使用它

安装嘲弄后,您可以开始生成模拟对象。假设我们在文件myinterface中有一个名为myinterface的接口。go,如下:

package mypackage

type MyInterface interface {
    MyMethod(a int, b string) (int, error)
}

上面的代码只是为了证明我们将仅使用MyInterface进行其参考,以进行其余的会话。您可以在此处为结构引用完整的代码。结构或实现也可以在不同的文件中。

package mypackage

type MyInterface interface {
    MyMethod(int, string) (int, error)
}

type MyComponent struct {
    i MyInterface
}

func (c *MyComponent) MyMethod() (int, error) {
    // Call the MyMethod method of the underlying interface
    return c.i.MyMethod(42, "hello")
}

func NewMyComponent(i MyInterface) *MyComponent {
    return &MyComponent{i: i}
}

要为此接口生成模拟对象,我们可以运行以下命令:

mockery --name MyInterface

这将在与原始接口文件同一目录中生成一个名为my_interface_mock.go的文件。生成的文件将包含一个实现接口和构造函数函数的结构,该函数可创建结构的实例。这是生成代码可能是什么样子的示例:

package mypackage

import "github.com/stretchr/testify/mock"

type MyInterfaceMock struct {
    mock.Mock
}

func (m *MyInterfaceMock) MyMethod(a int, b string) (int, error) {
    args := m.Called(a, b)
    return args.Int(0), args.Error(1)
}

func NewMyInterfaceMock() *MyInterfaceMock {
    return &MyInterfaceMock{}
}

您可以看到,MyInterfaceMock struct嵌入了一个mock.Mock字段,该字段为模拟方法调用提供了必要的功能。使用M.Called方法实现MyMethod方法,该方法记录了传递给该方法的参数并返回测试案例指定的结果。最后,NewMyInterFacemock函数返回模拟对象的新实例。

与测试框架集成

现在我们已经生成了模拟对象,我们可以使用它来测试我们的组件。嘲笑与各种测试框架集成,例如GO的内置测试包并作证。这是如何将模拟对象与GO测试软件包使用:
的示例

package mypackage_test

import (
    "testing"

    "github.com/stretchr/testify/assert"
    "github.com/mypackage"
    "github.com/mypackage/mocks"
)

func TestMyComponent(t *testing.T) {
    // Create a new instance of the mock object
    mock := new(mocks.MyInterface)

    // Set up the expected behavior of the mock object
    mock.On("MyMethod", 42, "hello").Return(100, nil)

    // Create an instance of the component under test
    c := mypackage.NewMyComponent(mock)

    // Call the method being tested
    result, err := c.MyMethod()

    // Check that the result and error match the expected values
    expected_result := 100
    expected_error := nil // or whatever error is expected
    if result != expected_result || err != expected_error {
        t.Errorf("unexpected result or error: got (%v, %v), expected (%v, %v)",
            result, err, expected_result, expected_error)
    }

    // Assert that the expected method was called with the expected arguments
    expected_args := []interface{}{42, "hello"}
    mock.AssertCalled(t, "MyMethod", expected_args...)
}

在此版本中,我们使用标准库测试软件包来定义名为TestMyComponent的测试功能。我们首先使用新函数创建模拟对象的新实例,该函数分配了其参数类型的零值,在这种情况下为mocks.MyInterface。然后,我们使用ON方法设置模拟对象的预期行为,该方法以模拟方法的名称及其参数,并返回可用于指定方法调用的返回值的*mock.Call值。

接下来,我们使用mypackage.NewMyComponent函数创建一个正在测试的组件的实例,将模拟对象作为参数传递。然后,我们调用正在测试的方法并将结果和错误值存储在结果和错误变量中。

要检查结果和错误是否与预期值匹配,我们将两个变量expected_resultexpected_error定义为我们期望的方法返回的值,并使用IF语句将它们与实际值进行比较。如果它们不匹配,我们使用t.Errorf函数来报告一个错误,其中包含实际和预期值的自定义消息。

最后,我们断言使用mock.AssertCalled方法的预期参数调用了预期方法,该方法以所模拟的方法的名称及其预期参数。如果未与预期参数调用该方法,则MOCK.SESTCALLCALLED将使测试失败,并报告一个错误,其中包含实际和预期的方法调用。

结论

模拟测试是隔离测试组件的必不可少的技术,而不必担心依赖关系。嘲弄是一种强大的工具,用于在GO中生成模拟对象,并且它与各种测试框架无缝集成。通过使用嘲弄生成模拟对象,您可以为您的GO应用程序编写更全面有效的单元测试。