Golang模拟数据库操作进行单元测试示例

golang模拟数据库操作进行单元测试示例

在Go语言开发中,对数据库操作进行单元测试时,通常不希望连接真实数据库。为了保证测试的快速性和可重复性,推荐使用接口抽象和模拟(mock)技术来替代实际的数据库调用。下面是一个使用Golang接口 + 模拟实现进行数据库操作单元测试的完整示例。

定义数据模型和数据库接口

假设我们有一个用户服务,需要查询和保存用户信息。先定义User结构体和数据库接口:

type User struct {    ID   int    Name string}type UserDB interface {    GetUser(id int) (*User, error)    SaveUser(user *User) error}

实现业务逻辑服务

UserService依赖UserDB接口,而不是具体实现,便于注入模拟对象:

type UserService struct {    db UserDB}func NewUserService(db UserDB) *UserService {    return &UserService{db: db}}func (s *UserService) GetUserName(id int) (string, error) {    user, err := s.db.GetUser(id)    if err != nil {        return "", err    }    if user == nil {        return "", fmt.Errorf("user not found")    }    return user.Name, nil}func (s *UserService) RenameUser(id int, name string) error {    user, err := s.db.GetUser(id)    if err != nil {        return err    }    if user == nil {        return fmt.Errorf("user not found")    }    user.Name = name    return s.db.SaveUser(user)}

编写模拟数据库实现用于测试

在测试包中创建一个模拟的UserDB实现,控制返回值以覆盖各种场景:

立即学习“go语言免费学习笔记(深入)”;

type MockUserDB struct {    users map[int]*User}func NewMockUserDB() *MockUserDB {    return &MockUserDB{        users: make(map[int]*User),    }}func (m *MockUserDB) GetUser(id int) (*User, error) {    if user, exists := m.users[id]; exists {        return user, nil    }    return nil, nil // 不返回错误,仅返回nil表示未找到}func (m *MockUserDB) SaveUser(user *User) error {    m.users[user.ID] = user    return nil}

编写单元测试

使用模拟数据库测试业务逻辑,无需启动真实数据库:

func TestUserService_GetUserName(t *testing.T) {    mockDB := NewMockUserDB()    mockDB.users[1] = &User{ID: 1, Name: "Alice"}    service := NewUserService(mockDB)    name, err := service.GetUserName(1)    if err != nil {        t.Fatalf("expected no error, got %v", err)    }    if name != "Alice" {        t.Errorf("expected name Alice, got %s", name)    }}func TestUserService_RenameUser(t *testing.T) {    mockDB := NewMockUserDB()    mockDB.users[2] = &User{ID: 2, Name: "Bob"}    service := NewUserService(mockDB)    err := service.RenameUser(2, "Bobby")    if err != nil {        t.Fatalf("expected no error, got %v", err)    }    updatedUser, _ := mockDB.GetUser(2)    if updatedUser.Name != "Bobby" {        t.Errorf("expected name Bobby, got %s", updatedUser.Name)    }}func TestUserService_RenameUser_NotFound(t *testing.T) {    mockDB := NewMockUserDB()    service := NewUserService(mockDB)    err := service.RenameUser(999, "Charlie")    if err == nil {        t.Fatal("expected error when user not found, got nil")    }}

基本上就这些。通过接口抽象+模拟实现,可以完全隔离数据库依赖,写出高效、可靠的单元测试。这种方式简单直接,不需要引入外部库如sqlmock或testify,适合中小型项目或学习理解mock原理。

以上就是Golang模拟数据库操作进行单元测试示例的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1408550.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年12月16日 00:11:49
下一篇 2025年12月16日 00:12:03

相关推荐

发表回复

登录后才能评论
关注微信