Maison > développement back-end > Golang > le corps du texte

TESTS GOLANG AVEC STRETCHR/TÉMOIGNAGE ET MOQUERIE

Linda Hamilton
Libérer: 2024-10-16 22:08:29
original
740 Les gens l'ont consulté

GOLANG TESTING WITH STRETCHR/TESTIFY AND MOCKERY

Let's go through a comprehensive example that covers common features of the stretchr/testify library and mockery for mocking in Golang. This example will include testing with assertions, using the require package for strict assertions, testing HTTP handlers, and mocking dependencies using mockery.

Scenario

Imagine we have a service that fetches user information from an external API. We want to test:

  • The service's functionality.
  • Its integration with an external client.
  • Mocking the external client.

Project Structure

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

Copier après la connexion

Code Overview

  1. user_client.go

    This file defines an interface for interacting with an external user API.

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

    This file contains a service that uses the UserClient to fetch user details.

    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
    }
    
    Copier après la connexion
  3. Generating Mocks with mockery

    You can generate mocks for the UserClient using mockery:

    mockery --name=UserClient --output=./mocks
    
    Copier après la connexion

    This will generate a mock in mocks/UserClient.go.

  4. service_test.go

    Now, let's write a test for the UserService using testify assertions and the mockery-generated mock.

        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)
        }
    
    
    Copier après la connexion

Key Points of This Example

  1. Assertions with testify:
    • assert and require packages are used for different types of checks.
    • require is used for checks that should fail the test immediately if they fail (e.g., checking for nil errors).
    • assert is used for checks that can continue even if they fail (e.g., comparing values).
  2. Mocking with mockery:
    • mockery generates a mock of the UserClient interface.
    • In the test, the mock is configured with.On() to specify expected inputs and .Return() to specify the outputs.
    • AssertExpectations verifies that the mocked method was called with the expected inputs.
  3. Testing Error Handling:
    • One test checks the successful scenario, while the other tests how the service handles an error from the UserClient.

This setup covers the basic functionality of stretchr/testify for assertions and mocking with mockery, providing a structured and maintainable approach to unit testing in Golang.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:dev.to
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal