- vừa được xem lúc

GOLANG TESTING WITH STRETCHR/TESTIFY AND MOCKERY

0 0 5

Người đăng: Truong Phung

Theo Viblo Asia

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 

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)
    }
    
  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
    }
    
  3. Generating Mocks with mockery
    You can generate mocks for the UserClient using mockery:

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

    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)
    } 

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).
  1. 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.
  1. 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.

Bình luận

Bài viết tương tự

- vừa được xem lúc

gRPC - Nó là gì và có nên sử dụng hay không?

Nhân một ngày rảnh rỗi, mình ngồi đọc lại RPC cũng như gRPC viết lại để nhớ lâu hơn. Vấn đề là gì và tại sao cần nó .

0 0 131

- vừa được xem lúc

Embedded Template in Go

Getting Start. Part of developing a web application usually revolves around working with HTML as user interface.

0 0 56

- vừa được xem lúc

Tạo Resful API đơn giản với Echo framework và MySQL

1. Giới thiệu.

0 0 60

- vừa được xem lúc

Sử dụng goquery trong golang để crawler thông tin các website Việt Nam bị deface trên mirror-h.org

. Trong bài viết này, mình sẽ cùng mọi người khám phá một package thu thập dữ liệu có tên là goquery của golang. Mục tiêu chính của chương trình crawler này sẽ là lấy thông tin các website Việt Nam bị deface (là tấn công, phá hoại website, làm thay đổi giao diện hiển thị của một trang web, khi người

0 0 237

- vừa được xem lúc

Tạo ứng dụng craw dữ liệu bing với Golang, Mysql driver

Chào mọi người . Lâu lâu ta lại gặp nhau 1 lần, để tiếp tục series chia sẻ kiến thức về tech, hôm nay mình sẽ tìm hiểu và chia sẻ về 1 ngôn ngữ đang khá hot trong cộng đồng IT đó là Golang.

0 0 75

- vừa được xem lúc

Golang: Rest api and routing using MUX

Routing with MUX. Let's create a simple CRUD api for a blog site. # All . GET articles/ .

0 0 54