313 lines
		
	
	
		
			7.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			313 lines
		
	
	
		
			7.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
// Copyright 2020 beego
 | 
						|
//
 | 
						|
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
						|
// you may not use this file except in compliance with the License.
 | 
						|
// You may obtain a copy of the License at
 | 
						|
//
 | 
						|
// http://www.apache.org/licenses/LICENSE-2.0
 | 
						|
//
 | 
						|
// Unless required by applicable law or agreed to in writing, software
 | 
						|
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
						|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
						|
// See the License for the specific language governing permissions and
 | 
						|
// limitations under the License.
 | 
						|
 | 
						|
package mock
 | 
						|
 | 
						|
import (
 | 
						|
	"context"
 | 
						|
	"database/sql"
 | 
						|
	"errors"
 | 
						|
	"testing"
 | 
						|
 | 
						|
	"github.com/stretchr/testify/assert"
 | 
						|
 | 
						|
	"github.com/beego/beego/v2/client/orm"
 | 
						|
)
 | 
						|
 | 
						|
const mockErrorMsg = "mock error"
 | 
						|
 | 
						|
func init() {
 | 
						|
	orm.RegisterModel(&User{})
 | 
						|
}
 | 
						|
 | 
						|
func TestMockDBStats(t *testing.T) {
 | 
						|
	s := StartMock()
 | 
						|
	defer s.Clear()
 | 
						|
	stats := &sql.DBStats{}
 | 
						|
	s.Mock(MockDBStats(stats))
 | 
						|
 | 
						|
	o := orm.NewOrm()
 | 
						|
 | 
						|
	res := o.DBStats()
 | 
						|
 | 
						|
	assert.Equal(t, stats, res)
 | 
						|
}
 | 
						|
 | 
						|
func TestMockDeleteWithCtx(t *testing.T) {
 | 
						|
	s := StartMock()
 | 
						|
	defer s.Clear()
 | 
						|
	s.Mock(MockDeleteWithCtx((&User{}).TableName(), 12, nil))
 | 
						|
	o := orm.NewOrm()
 | 
						|
	rows, err := o.Delete(&User{})
 | 
						|
	assert.Equal(t, int64(12), rows)
 | 
						|
	assert.Nil(t, err)
 | 
						|
}
 | 
						|
 | 
						|
func TestMockInsertOrUpdateWithCtx(t *testing.T) {
 | 
						|
	s := StartMock()
 | 
						|
	defer s.Clear()
 | 
						|
	s.Mock(MockInsertOrUpdateWithCtx((&User{}).TableName(), 12, nil))
 | 
						|
	o := orm.NewOrm()
 | 
						|
	id, err := o.InsertOrUpdate(&User{})
 | 
						|
	assert.Equal(t, int64(12), id)
 | 
						|
	assert.Nil(t, err)
 | 
						|
}
 | 
						|
 | 
						|
func TestMockRead(t *testing.T) {
 | 
						|
	s := StartMock()
 | 
						|
	defer s.Clear()
 | 
						|
	err := errors.New(mockErrorMsg)
 | 
						|
	s.Mock(MockRead((&User{}).TableName(), func(data interface{}) {
 | 
						|
		u := data.(*User)
 | 
						|
		u.Name = "Tom"
 | 
						|
	}, err))
 | 
						|
	o := orm.NewOrm()
 | 
						|
	u := &User{}
 | 
						|
	e := o.Read(u)
 | 
						|
	assert.Equal(t, err, e)
 | 
						|
	assert.Equal(t, "Tom", u.Name)
 | 
						|
}
 | 
						|
 | 
						|
func TestMockQueryM2MWithCtx(t *testing.T) {
 | 
						|
	s := StartMock()
 | 
						|
	defer s.Clear()
 | 
						|
	mock := &DoNothingQueryM2Mer{}
 | 
						|
	s.Mock(MockQueryM2MWithCtx((&User{}).TableName(), "Tags", mock))
 | 
						|
	o := orm.NewOrm()
 | 
						|
	res := o.QueryM2M(&User{}, "Tags")
 | 
						|
	assert.Equal(t, mock, res)
 | 
						|
}
 | 
						|
 | 
						|
func TestMockQueryTableWithCtx(t *testing.T) {
 | 
						|
	s := StartMock()
 | 
						|
	defer s.Clear()
 | 
						|
	mock := &DoNothingQuerySetter{}
 | 
						|
	s.Mock(MockQueryTableWithCtx((&User{}).TableName(), mock))
 | 
						|
	o := orm.NewOrm()
 | 
						|
	res := o.QueryTable(&User{})
 | 
						|
	assert.Equal(t, mock, res)
 | 
						|
}
 | 
						|
 | 
						|
func TestMockTable(t *testing.T) {
 | 
						|
	s := StartMock()
 | 
						|
	defer s.Clear()
 | 
						|
	mock := errors.New(mockErrorMsg)
 | 
						|
	s.Mock(MockTable((&User{}).TableName(), mock))
 | 
						|
	o := orm.NewOrm()
 | 
						|
	res := o.Read(&User{})
 | 
						|
	assert.Equal(t, mock, res)
 | 
						|
}
 | 
						|
 | 
						|
func TestMockInsertMultiWithCtx(t *testing.T) {
 | 
						|
	s := StartMock()
 | 
						|
	defer s.Clear()
 | 
						|
	mock := errors.New(mockErrorMsg)
 | 
						|
	s.Mock(MockInsertMultiWithCtx((&User{}).TableName(), 12, mock))
 | 
						|
	o := orm.NewOrm()
 | 
						|
	res, err := o.InsertMulti(11, []interface{}{&User{}})
 | 
						|
	assert.Equal(t, int64(12), res)
 | 
						|
	assert.Equal(t, mock, err)
 | 
						|
}
 | 
						|
 | 
						|
func TestMockInsertWithCtx(t *testing.T) {
 | 
						|
	s := StartMock()
 | 
						|
	defer s.Clear()
 | 
						|
	mock := errors.New(mockErrorMsg)
 | 
						|
	s.Mock(MockInsertWithCtx((&User{}).TableName(), 13, mock))
 | 
						|
	o := orm.NewOrm()
 | 
						|
	res, err := o.Insert(&User{})
 | 
						|
	assert.Equal(t, int64(13), res)
 | 
						|
	assert.Equal(t, mock, err)
 | 
						|
}
 | 
						|
 | 
						|
func TestMockUpdateWithCtx(t *testing.T) {
 | 
						|
	s := StartMock()
 | 
						|
	defer s.Clear()
 | 
						|
	mock := errors.New(mockErrorMsg)
 | 
						|
	s.Mock(MockUpdateWithCtx((&User{}).TableName(), 12, mock))
 | 
						|
	o := orm.NewOrm()
 | 
						|
	res, err := o.Update(&User{})
 | 
						|
	assert.Equal(t, int64(12), res)
 | 
						|
	assert.Equal(t, mock, err)
 | 
						|
}
 | 
						|
 | 
						|
func TestMockLoadRelatedWithCtx(t *testing.T) {
 | 
						|
	s := StartMock()
 | 
						|
	defer s.Clear()
 | 
						|
	mock := errors.New(mockErrorMsg)
 | 
						|
	s.Mock(MockLoadRelatedWithCtx((&User{}).TableName(), "T", 12, mock))
 | 
						|
	o := orm.NewOrm()
 | 
						|
	res, err := o.LoadRelated(&User{}, "T")
 | 
						|
	assert.Equal(t, int64(12), res)
 | 
						|
	assert.Equal(t, mock, err)
 | 
						|
}
 | 
						|
 | 
						|
func TestMockMethod(t *testing.T) {
 | 
						|
	s := StartMock()
 | 
						|
	defer s.Clear()
 | 
						|
	mock := errors.New(mockErrorMsg)
 | 
						|
	s.Mock(MockMethod("ReadWithCtx", mock))
 | 
						|
	o := orm.NewOrm()
 | 
						|
	err := o.Read(&User{})
 | 
						|
	assert.Equal(t, mock, err)
 | 
						|
}
 | 
						|
 | 
						|
func TestMockReadForUpdateWithCtx(t *testing.T) {
 | 
						|
	s := StartMock()
 | 
						|
	defer s.Clear()
 | 
						|
	mock := errors.New(mockErrorMsg)
 | 
						|
	s.Mock(MockReadForUpdateWithCtx((&User{}).TableName(), func(data interface{}) {
 | 
						|
		u := data.(*User)
 | 
						|
		u.Name = "Tom"
 | 
						|
	}, mock))
 | 
						|
	o := orm.NewOrm()
 | 
						|
	u := &User{}
 | 
						|
	err := o.ReadForUpdate(u)
 | 
						|
	assert.Equal(t, mock, err)
 | 
						|
	assert.Equal(t, "Tom", u.Name)
 | 
						|
}
 | 
						|
 | 
						|
func TestMockRawWithCtx(t *testing.T) {
 | 
						|
	s := StartMock()
 | 
						|
	defer s.Clear()
 | 
						|
	mock := &DoNothingRawSetter{}
 | 
						|
	s.Mock(MockRawWithCtx(mock))
 | 
						|
	o := orm.NewOrm()
 | 
						|
	res := o.Raw("")
 | 
						|
	assert.Equal(t, mock, res)
 | 
						|
}
 | 
						|
 | 
						|
func TestMockReadOrCreateWithCtx(t *testing.T) {
 | 
						|
	s := StartMock()
 | 
						|
	defer s.Clear()
 | 
						|
	mock := errors.New(mockErrorMsg)
 | 
						|
	s.Mock(MockReadOrCreateWithCtx((&User{}).TableName(), func(data interface{}) {
 | 
						|
		u := data.(*User)
 | 
						|
		u.Name = "Tom"
 | 
						|
	}, false, 12, mock))
 | 
						|
	o := orm.NewOrm()
 | 
						|
	u := &User{}
 | 
						|
	inserted, id, err := o.ReadOrCreate(u, "")
 | 
						|
	assert.Equal(t, mock, err)
 | 
						|
	assert.Equal(t, int64(12), id)
 | 
						|
	assert.False(t, inserted)
 | 
						|
	assert.Equal(t, "Tom", u.Name)
 | 
						|
}
 | 
						|
 | 
						|
func TestTransactionClosure(t *testing.T) {
 | 
						|
	s := StartMock()
 | 
						|
	defer s.Clear()
 | 
						|
	mock := errors.New(mockErrorMsg)
 | 
						|
	s.Mock(MockRead((&User{}).TableName(), func(data interface{}) {
 | 
						|
		u := data.(*User)
 | 
						|
		u.Name = "Tom"
 | 
						|
	}, mock))
 | 
						|
	u, err := originalTxUsingClosure()
 | 
						|
	assert.Equal(t, mock, err)
 | 
						|
	assert.Equal(t, "Tom", u.Name)
 | 
						|
}
 | 
						|
 | 
						|
func TestTransactionManually(t *testing.T) {
 | 
						|
	s := StartMock()
 | 
						|
	defer s.Clear()
 | 
						|
	mock := errors.New(mockErrorMsg)
 | 
						|
	s.Mock(MockRead((&User{}).TableName(), func(data interface{}) {
 | 
						|
		u := data.(*User)
 | 
						|
		u.Name = "Tom"
 | 
						|
	}, mock))
 | 
						|
	u, err := originalTxManually()
 | 
						|
	assert.Equal(t, mock, err)
 | 
						|
	assert.Equal(t, "Tom", u.Name)
 | 
						|
}
 | 
						|
 | 
						|
func TestTransactionRollback(t *testing.T) {
 | 
						|
	s := StartMock()
 | 
						|
	defer s.Clear()
 | 
						|
	mock := errors.New(mockErrorMsg)
 | 
						|
	s.Mock(MockRead((&User{}).TableName(), nil, errors.New("read error")))
 | 
						|
	s.Mock(MockRollback(mock))
 | 
						|
	_, err := originalTx()
 | 
						|
	assert.Equal(t, mock, err)
 | 
						|
}
 | 
						|
 | 
						|
func TestTransactionRollbackUnlessCommit(t *testing.T)  {
 | 
						|
	s := StartMock()
 | 
						|
	defer s.Clear()
 | 
						|
	mock := errors.New(mockErrorMsg)
 | 
						|
	s.Mock(MockRollbackUnlessCommit(mock))
 | 
						|
 | 
						|
	//u := &User{}
 | 
						|
	o := orm.NewOrm()
 | 
						|
	txOrm, _ := o.Begin()
 | 
						|
	err := txOrm.RollbackUnlessCommit()
 | 
						|
	assert.Equal(t, mock, err)
 | 
						|
}
 | 
						|
 | 
						|
func TestTransactionCommit(t *testing.T) {
 | 
						|
	s := StartMock()
 | 
						|
	defer s.Clear()
 | 
						|
	mock := errors.New(mockErrorMsg)
 | 
						|
	s.Mock(MockRead((&User{}).TableName(), func(data interface{}) {
 | 
						|
		u := data.(*User)
 | 
						|
		u.Name = "Tom"
 | 
						|
	}, nil))
 | 
						|
	s.Mock(MockCommit(mock))
 | 
						|
	u, err := originalTx()
 | 
						|
	assert.Equal(t, mock, err)
 | 
						|
	assert.Equal(t, "Tom", u.Name)
 | 
						|
}
 | 
						|
 | 
						|
func originalTx() (*User, error) {
 | 
						|
	u := &User{}
 | 
						|
	o := orm.NewOrm()
 | 
						|
	txOrm, _ := o.Begin()
 | 
						|
	err := txOrm.Read(u)
 | 
						|
	if err == nil {
 | 
						|
		err = txOrm.Commit()
 | 
						|
		return u, err
 | 
						|
	} else {
 | 
						|
		err = txOrm.Rollback()
 | 
						|
		return nil, err
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func originalTxManually() (*User, error) {
 | 
						|
	u := &User{}
 | 
						|
	o := orm.NewOrm()
 | 
						|
	txOrm, _ := o.Begin()
 | 
						|
	err := txOrm.Read(u)
 | 
						|
	_ = txOrm.Commit()
 | 
						|
	return u, err
 | 
						|
}
 | 
						|
 | 
						|
func originalTxUsingClosure() (*User, error) {
 | 
						|
	u := &User{}
 | 
						|
	var err error
 | 
						|
	o := orm.NewOrm()
 | 
						|
	_ = o.DoTx(func(ctx context.Context, txOrm orm.TxOrmer) error {
 | 
						|
		err = txOrm.Read(u)
 | 
						|
		return nil
 | 
						|
	})
 | 
						|
	return u, err
 | 
						|
}
 | 
						|
 | 
						|
type User struct {
 | 
						|
	Id   int
 | 
						|
	Name string
 | 
						|
}
 | 
						|
 | 
						|
func (u *User) TableName() string {
 | 
						|
	return "user"
 | 
						|
}
 |