Configs2026年4月13日·1 分钟阅读

Testify — Go Testing Toolkit with Assertions and Mocks

Testify is the most popular Go testing toolkit. It provides expressive assertions (assert/require), powerful mocking, and test suites with setup/teardown — making Go tests more readable and maintainable than the standard library alone.

AI
AI Open Source · Community
快速使用

先拿来用,再决定要不要深挖

这里应该同时让用户和 Agent 知道第一步该复制什么、安装什么、落到哪里。

package mypackage

import (
    "testing"
    "github.com/stretchr/testify/assert"
    "github.com/stretchr/testify/require"
)

func TestAdd(t *testing.T) {
    result := Add(2, 3)
    assert.Equal(t, 5, result, "2+3 should equal 5")
    assert.NotNil(t, result)
    assert.Greater(t, result, 0)
}

func TestDatabaseConnection(t *testing.T) {
    db, err := Connect("localhost:5432")
    require.NoError(t, err)       // stops test on failure
    require.NotNil(t, db)
    defer db.Close()

    users, err := db.GetUsers()
    assert.NoError(t, err)        // continues test on failure
    assert.Len(t, users, 3)
}

Introduction

Testify extends Go standard testing with assertions that make tests more readable and mocks that make testing easier. Instead of writing verbose if-else checks with t.Errorf(), you write assert.Equal(t, expected, actual) — clear, concise, and with helpful error messages.

With over 26,000 GitHub stars, Testify is used in virtually every Go project that goes beyond trivial testing. Its assert, require, mock, and suite packages cover the full spectrum of testing needs.

What Testify Does

Testify provides three main packages: assert (soft assertions that continue on failure), require (hard assertions that stop the test), and mock (interface mocking with expectations). The suite package adds setup/teardown lifecycle methods similar to JUnit or pytest fixtures.

Architecture Overview

[Testify Packages]
        |
+-------+-------+-------+
|       |       |       |
[assert]  [require] [mock]
Soft      Hard      Interface
assertions assertions mocking
(continue  (stop on  with
on fail)   fail)     expectations
        |
   [suite]
   Test suites with
   SetupTest()
   TearDownTest()
   SetupSuite()
   TearDownSuite()

Self-Hosting & Configuration

// Mocking example
type UserRepository interface {
    GetUser(id int) (*User, error)
    SaveUser(user *User) error
}

// Generated or hand-written mock
type MockUserRepo struct {
    mock.Mock
}

func (m *MockUserRepo) GetUser(id int) (*User, error) {
    args := m.Called(id)
    if args.Get(0) == nil {
        return nil, args.Error(1)
    }
    return args.Get(0).(*User), args.Error(1)
}

func (m *MockUserRepo) SaveUser(user *User) error {
    return m.Called(user).Error(0)
}

// Test with mock
func TestGetUserService(t *testing.T) {
    mockRepo := new(MockUserRepo)
    mockRepo.On("GetUser", 1).Return(&User{ID: 1, Name: "Alice"}, nil)
    mockRepo.On("GetUser", 999).Return(nil, errors.New("not found"))

    service := NewUserService(mockRepo)

    user, err := service.GetUser(1)
    assert.NoError(t, err)
    assert.Equal(t, "Alice", user.Name)

    _, err = service.GetUser(999)
    assert.Error(t, err)

    mockRepo.AssertExpectations(t)
}
// Test suite with setup/teardown
type UserServiceSuite struct {
    suite.Suite
    db      *sql.DB
    service *UserService
}

func (s *UserServiceSuite) SetupSuite() {
    s.db, _ = sql.Open("postgres", testDSN)
    s.service = NewUserService(s.db)
}

func (s *UserServiceSuite) TearDownSuite() {
    s.db.Close()
}

func (s *UserServiceSuite) SetupTest() {
    s.db.Exec("DELETE FROM users")
}

func (s *UserServiceSuite) TestCreateUser() {
    user, err := s.service.Create("Alice")
    s.NoError(err)
    s.Equal("Alice", user.Name)
}

func TestUserServiceSuite(t *testing.T) {
    suite.Run(t, new(UserServiceSuite))
}

Key Features

  • assert — 70+ assertion functions (Equal, Contains, Len, Error, etc.)
  • require — same assertions but stops test on failure
  • mock — interface mocking with expected calls and return values
  • suite — test suites with SetupTest/TearDownTest lifecycle
  • Helpful Messages — clear diff output on assertion failures
  • Custom Messages — add context to any assertion
  • HTTP Testing — assert on HTTP responses (status, body, headers)
  • Standard Compatible — works with go test, no special runner needed

Comparison with Similar Tools

Feature Testify gomock gocheck is standard lib
Assertions 70+ No Yes Minimal Manual
Mocking Built-in Code-gen (mockgen) No No Manual
Suites Yes No Yes No No
Error Messages Excellent Good Good Good Manual
Code Gen No Yes (mockgen) No No No
Popularity Dominant Popular Declining Growing Built-in

FAQ

Q: assert vs require — when to use which? A: Use require for preconditions (if this fails, nothing else makes sense). Use assert for verifications (check multiple things even if one fails). Example: require.NoError for setup, assert.Equal for validations.

Q: Should I use testify mocks or gomock? A: Testify mocks for hand-written mocks with flexible expectations. gomock with mockgen for auto-generated mocks from interfaces. Testify is simpler; gomock is more rigorous.

Q: Is testify considered idiomatic Go? A: Purists prefer the standard library, but testify is the most pragmatic choice. The Go team does not officially endorse testing libraries, but testify is the community standard.

Q: How do I generate mocks automatically? A: Use mockery (github.com/vektra/mockery) to auto-generate testify mocks from interfaces: "mockery --all" generates mock files for all interfaces in your project.

Sources

讨论

登录后参与讨论。
还没有评论,来写第一条吧。

相关资产