GOLANG UNIT TESTING VỚI STRETCHR/TESTIFY VÀ MOCKERY

0 0 0

Người đăng: Truong Phung

Theo Viblo Asia

Chúng ta hãy cùng đi qua một ví dụ bao gồm các tính năng phổ biến của thư viện stretchr/testifymockery dùng cho việc mocking trong Golang. Ví dụ này sẽ bao gồm việc testing với assertions, sử dụng gói require cho các assertions nghiêm ngặt, test HTTP handlers, và mocking các dependencies bằng mockery.

Kịch bản

Giả sử chúng ta có một service lấy thông tin người dùng từ một API bên ngoài. Chúng ta muốn test những mục sau:

  • Chức năng của service.
  • Tích hợp của nó với một external client.
  • Mocking external client.

Cấu trúc dự án

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

Tổng quan về source code

  1. user_client.go
    File này định nghĩa một interface để tương tác với một external user API.

    package project type User struct { ID int Name string
    } type UserClient interface { GetUserByID(id int) (*User, error)
    }
    
  2. service.go
    File này chứa một service sử dụng UserClient để lấy thông tin người dùng..

    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. Tạo mocks với mockery
    Bạn có thể tạo mocks cho UserClient với mockery:

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

    Lệnh này sẽ tạo ra một file mock trong mocks/UserClient.go.

  4. service_test.go
    Bây giờ, chúng ta sẽ viết test cho UserService sử dụng testify assertions và mocked files được tạo trước đó với mockery.

    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) { // Tạo một mock client mới mockClient := new(mocks.UserClient) // Định nghĩa kết quả mà mock sẽ trả về khi gọi `GetUserByID` mockClient.On("GetUserByID", 1).Return(&project.User{ ID: 1, Name: "John Doe", }, nil) // Tạo UserService với mock client service := project.NewUserService(mockClient) // Test phương thức GetUserDetails result, err := service.GetUserDetails(1) // Sử dụng `require` cho các kiểm tra lỗi require.NoError(t, err) require.NotEmpty(t, result) // Sử dụng `assert` để kiểm tra giá trị kết quả assert.Equal(t, "User: John Doe (ID: 1)", result) // Đảm bảo rằng phương thức `GetUserByID` đã được gọi chính xác một lần mockClient.AssertExpectations(t)
    } func TestUserService_GetUserDetails_Error(t *testing.T) { // Tạo một mock client mới mockClient := new(mocks.UserClient) // Định nghĩa kết quả mà mock sẽ trả về khi gọi `GetUserByID` và có lỗi xảy ra mockClient.On("GetUserByID", 2).Return(nil, errors.New("user not found")) // Tạo UserService với mock client service := project.NewUserService(mockClient) // Test phương thức GetUserDetails result, err := service.GetUserDetails(2) // Sử dụng `require` cho các kiểm tra lỗi require.Error(t, err) assert.Contains(t, err.Error(), "user not found") // Đảm bảo rằng kết quả là rỗng assert.Empty(t, result) // Đảm bảo rằng phương thức `GetUserByID` đã được gọi chính xác một lần mockClient.AssertExpectations(t)
    } 

Những điểm chính của ví dụ trên

  1. Assertions với testify:
  • Các gói assertrequire được sử dụng cho các kiểu kiểm tra khác nhau.
    • requiređược sử dụng cho các test case cần dừng bài test ngay lập tức nếu thất bại (ví dụ: kiểm tra lỗi nil ).
    • assert được sử dụng cho các test case có thể tiếp tục ngay cả khi chúng fail (ví dụ: so sánh giá trị).
  1. Mocking với mockery:
  • mockery tạo ra một mock của interface UserClient .
    • Trong bài test, mock được cấu hình bằng.On() để chỉ định input mong muốn và .Return() để chỉ định output tương ứng.
    • AssertExpectations xác minh rằng phương thức mock đã được gọi với expected inputs.
  1. Testing và xử lý lỗi:
  • Một bài test kiểm tra trường hợp success, trong khi bài còn lại kiểm tra cách service xử lý lỗi từ UserClient.

Cài đặt trên khái quát các chức năng cơ bản của stretchr/testify cho assertions và mocking với mockery, cung cấp một cách tiếp cận có cấu trúc và dễ bảo trì cho unit tests trong Golang. Cảm ơn bạn đã xem hết.

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 129

- 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 55

- 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 59

- 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 235

- 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 53