zoukankan      html  css  js  c++  java
  • go学习-go-sqlmock数据库操作测试

    sqlmock 是一个实现 sql/driver 的mock库。它不需要建立真正的数据库连接就可以在测试中模拟任何 sql 驱动程序的行为。使用它可以很方便的在编写单元测试的时候mock sql语句的执行结果。

    安装mockgen

    go get github.com/DATA-DOG/go-sqlmock

    针对测试的数据库操作函数编写单元测试(本例为向数据库表插入数据)

    数据库操作函数employees.go

    func (repo *EmployeesRepository) CreateEmployee(employee *domain.Employees) (err error) {
    	err = repo.db.Debug().Create(&employee).Error
    	if err != nil {
    		err = fmt.Errorf("[repository.r.CreateEmployee] failed: employee = %+v, error = %w ", employee, err)
    		return
    	}
    	return
    }
    

    domain.Employees 数据结构

    package domain
    
    import(
    	"time"
    )
    type Employees struct{
    	ID   int `json:"id" gorm:"primary_key"`
    	Code string        `json:"code"`
    	Name string     `json:"name"`
    	DepartmentID int `json:"departmentid"`
      	CreatedAt time.Time
      	UpdatedAt time.Time
      	DeletedAt *time.Time
    }
    

    针对测试的数据库操作函数编写单元测试employees_test.go

    package impl
    
    import (
    	"testing"
    	"github.com/DATA-DOG/go-sqlmock"
    	"github.com/magiconair/properties/assert"
    	"gorm.io/driver/postgres"
    	"gorm.io/gorm"
    
    	"server/domain"
    )
    
    func getDBMock() (*gorm.DB, sqlmock.Sqlmock, error) {
    // mock一个*sql.DB对象,不需要连接真实的数据库
    	db, mock, err := sqlmock.New()
    	if err != nil {
    		return nil, nil, err
    	}
            //测试时不需要真正连接数据库
    	gdb, err := gorm.Open(postgres.New(postgres.Config{
    		DriverName:           "postgres",
    		PreferSimpleProtocol: true,
    		Conn:                 db,
    	}), &gorm.Config{})
    	if err != nil {
    		return nil, nil, err
    	}
    	return gdb, mock, nil
    }
    func TestEmployeesRepository_CreateEmployees(t *testing.T) {
    	type fields struct {
    		db *gorm.DB
    	}
    	type args struct {
    		employees *domain.Employees
    	}
    	db, mock, err := getDBMock()
    	assert.Equal(t, err, nil)
    	tests := []struct {
    		name    string
    		fields  fields
    		args    args
    		invoke  func(args)
    		wantErr bool
    	}{
    		{
    			name: "create Employees successful",
    			fields: fields{
    				db: db,
    			},
    			args: args{employees: &domain.Employees{
    				ID:0,
    				Code:      "1",
    				Name:"zhangsan",
    				DepartmentID:1,
    			}},
    			invoke: func(args args) {
    				mock.ExpectQuery("INSERT INTO (.+)").WithArgs(
    					args.employees.Code, args.employees.Name,args.employees.DepartmentID,sqlmock.AnyArg(),sqlmock.AnyArg(),sqlmock.AnyArg()).
    					WillReturnRows(sqlmock.NewRows([]string{"ID"}).AddRow(1))
    			},
    		},
    		{
    			name: "create Employees failed",
    			fields: fields{
    				db: db,
    			},
    			args: args{employees: &domain.Employees{
    				Code:      "1",
    				Name:"zhangsan",
    				DepartmentID:2,
    			}},
    			invoke: func(args args) {
    				mock.ExpectQuery("INSERT INTO (.+)").WithArgs(
    					args.employees.Code,args.employees.Name,args.employees.DepartmentID,sqlmock.AnyArg(),sqlmock.AnyArg(),sqlmock.AnyArg()).
    					WillReturnError(gorm.ErrInvalidData)
    			},
    			wantErr: true,
    		},
    	}
    	for _, tt := range tests {
    		t.Run(tt.name, func(t *testing.T) {
    			c := &EmployeesRepository{
    				db: tt.fields.db,
    			}
    			tt.invoke(tt.args)
    			if err := c.CreateEmployee(tt.args.employees); (err != nil) != tt.wantErr {
    				t.Errorf("CreateEmployees() error = %v, wantErr %v", err, tt.wantErr)
    			}
    		})
    	}
    }
    
    
    

    在测试文件所在目录下,执行go test -v
    执行结果
    21:46:24.176',NULL) RETURNING "id"
    --- PASS: TestEmployeesRepository_CreateEmployees (0.00s)
    --- PASS: TestEmployeesRepository_CreateEmployees/create_Employees_successful (0.00s)
    --- PASS: TestEmployeesRepository_CreateEmployees/create_Employees_failed (0.00s)
    PASS
    ok server/repository/impl 0.008s

    所有博客均为自己学习的笔记。如有错误敬请理解。
  • 相关阅读:
    element-ui分页组件修改当前页current-page后current-change事件不触发
    使用element-ui 的table 组件 表格线条不对齐
    vue 禁止浏览器自带的后退功能
    echart 柱图的(层叠柱图和柱图)label只显示总数 ,折线图的legent上显示总数
    element-ui table组件,分别设置表头和表格内容的居中,自定义渲染
    vue-cli-3+element-ui 按需引入element-ui的配置
    今天使用ElementUI与vue-quill-editor的时候发现,富文本编辑框选项对齐出现了点问题。
    vue-router 切换页面的时候,页面没有请求,
    msvcp140.dll缺失解决办法
    CTF中RSA题目的pem文件处理
  • 原文地址:https://www.cnblogs.com/tangtang-benben/p/15387890.html
Copyright © 2011-2022 走看看