首页 >后端开发 >Golang >使用 STRETCHR/TESTIFY 和 MOCKERY 进行 GOL 测试

使用 STRETCHR/TESTIFY 和 MOCKERY 进行 GOL 测试

Linda Hamilton
Linda Hamilton原创
2024-10-16 22:08:29766浏览

GOLANG TESTING WITH STRETCHR/TESTIFY AND MOCKERY

让我们看一个全面的示例,其中涵盖了stretchr/testify库的常见功能以及Golang中的mockery。此示例将包括使用断言进行测试、使用 require 包进行严格断言、测试 HTTP 处理程序以及使用 mockery 模拟依赖项。

设想

假设我们有一个从外部 API 获取用户信息的服务。我们想要测试:

  • 服务的功能。
  • 它与外部客户端的集成。
  • 嘲笑外部客户端。

项目结构

/project
│
├── main.go
├── service.go
├── service_test.go
├── user_client.go
├── mocks/
│   └── UserClient.go (generated by mockery)
└── go.mod

代码概述

  1. user_client.go

    该文件定义了与外部用户 API 交互的接口。

    package project
    
    type User struct {
        ID   int
        Name string
    }
    
    type UserClient interface {
        GetUserByID(id int) (*User, error)
    }
    
  2. service.go

    该文件包含一个使用 UserClient 获取用户详细信息的服务。

    package project
    
    import "fmt"
    
    type UserService struct {
        client UserClient
    }
    
    func NewUserService(client UserClient) *UserService {
        return &UserService{client: client}
    }
    
    func (s *UserService) GetUserDetails(id int) (string, error) {
        user, err := s.client.GetUserByID(id)
        if err != nil {
            return "", fmt.Errorf("failed to get user: %w", err)
        }
    
        return fmt.Sprintf("User: %s (ID: %d)", user.Name, user.ID), nil
    }
    
  3. 使用嘲讽生成模拟

    您可以使用 mockery 为 UserClient 生成模拟:

    mockery --name=UserClient --output=./mocks
    

    这将在mocks/UserClient.go 中生成一个模拟。

  4. service_test.go

    现在,让我们使用 testify 断言和模拟生成的模拟为 UserService 编写一个测试。

        package project_test
    
        import (
            "errors"
            "testing"
    
            "github.com/stretchr/testify/assert"
            "github.com/stretchr/testify/require"
            "github.com/stretchr/testify/mock"
            "project"
            "project/mocks"
        )
    
        func TestUserService_GetUserDetails_Success(t *testing.T) {
            // Create a new mock client
            mockClient := new(mocks.UserClient)
    
            // Define what the mock should return when `GetUserByID` is called
            mockClient.On("GetUserByID", 1).Return(&project.User{
                ID:   1,
                Name: "John Doe",
            }, nil)
    
            // Create the UserService with the mock client
            service := project.NewUserService(mockClient)
    
            // Test the GetUserDetails method
            result, err := service.GetUserDetails(1)
    
            // Use `require` for error checks
            require.NoError(t, err)
            require.NotEmpty(t, result)
    
            // Use `assert` for value checks
            assert.Equal(t, "User: John Doe (ID: 1)", result)
    
            // Ensure that the `GetUserByID` method was called exactly once
            mockClient.AssertExpectations(t)
        }
    
        func TestUserService_GetUserDetails_Error(t *testing.T) {
            // Create a new mock client
            mockClient := new(mocks.UserClient)
    
            // Define what the mock should return when `GetUserByID` is called with an error
            mockClient.On("GetUserByID", 2).Return(nil, errors.New("user not found"))
    
            // Create the UserService with the mock client
            service := project.NewUserService(mockClient)
    
            // Test the GetUserDetails method
            result, err := service.GetUserDetails(2)
    
            // Use `require` for error checks
            require.Error(t, err)
            assert.Contains(t, err.Error(), "user not found")
    
            // Ensure that the result is empty
            assert.Empty(t, result)
    
            // Ensure that the `GetUserByID` method was called exactly once
            mockClient.AssertExpectations(t)
        }
    
    

本例的要点

  1. 带有的断言证明:
    • assert 和 require 包用于不同类型的检查。
    • require 用于检查如果失败则应立即使测试失败(例如,检查 nil 错误)。
    • 断言用于即使失败也可以继续的检查(例如,比较值)。
  2. 嘲笑来嘲笑:
    • mockery 生成 UserClient 接口的模拟。
    • 在测试中,模拟配置为 .On() 来指定预期输入,并使用 .Return() 来指定输出。
    • AssertExpectations 验证是否使用预期输入调用了模拟方法。
  3. 测试错误处理
    • 一个测试检查成功场景,而另一个测试则测试服务如何处理来自 UserClient 的错误。

此设置涵盖了stretcher/testify 的断言和模拟的基本功能,为 Golang 中的单元测试提供了结构化且可维护的方法。

以上是使用 STRETCHR/TESTIFY 和 MOCKERY 进行 GOL 测试的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn