当前位置:网站首页>Use of go testing framework gomock

Use of go testing framework gomock

2022-06-24 04:54:00 Johns

One . Introduce

gomock yes golang Interface level of official development and maintenance mock programme , Contains GoMock Bao He mockgen The tools are two parts , among GoMock Package completes the life cycle management of pile objects ,mockgen Tools are used to generate interface Corresponding Mock Class source file . To use gomock A prerequisite of is that modules must rely on each other through interfaces , Instead of relying on concrete implementation , otherwise mock It will be very difficult . This tool is not widely used in the industry , The main reason is that there are too many limitations , So we just need to know how to use it .

github Address :https://github.com/golang/mock

Two . Use

1. install

go get -u github.com/golang/mock/gomock
go install github.com/golang/mock/mockgen

2. Quick start

First step : Defining interfaces , Note that this tool supports interface generation mock, Other types of methods do not support .

package dao

import (
	"fmt"
	_ "github.com/golang/mock/mockgen/model"
)

//  User persistence layer operation object 
type UserDao interface {
	Update(id, name, phoneNumber string) int64
	Update2(param ...string) int64
	Add(name, phoneNumber string) (int64, error)
	Select(id string) int64
	Delete(id string) int64
}

type userDao struct{}

func (u userDao) Update(id, name, phoneNumber string) int64 {
	fmt.Println(id, name, phoneNumber)
	return 1
}

The second step : Build with command mock class

mockgen  -destination mock_user_dao.go -package dao -source user_dao.go 

If the command is too long , Can be directly in UserDao Add one to it go:generate The comments are as follows

package dao

import (
	"fmt"
	_ "github.com/golang/mock/mockgen/model"
)

//go:generate mockgen -destination mock_user_dao.go -package dao -source user_dao.go
//  User persistence layer operation object 
type UserDao interface {
	Update(id, name, phoneNumber string) int64
	Update2(param ...string) int64
	Add(name, phoneNumber string) (int64, error)
	Select(id string) int64
	Delete(id string) int64
}
...

Then in the directory of the current package bash perform go generate It can also generate mock Of documents .

The third step : Customize mock Implement and assert

package dao

import (
	"errors"
	"github.com/golang/mock/gomock"
	"github.com/stretchr/testify/assert"
	"testing"
)

/**
 * @Description
 * @Author guirongguo
 * @Email 
 * @Date 2021/8/31 20:37
 **/

func Test_userDao(t *testing.T) {

	// step1.  Initialize a mock controller
	mockCtrl := gomock.NewController(t)
	defer mockCtrl.Finish()
	mockObj := NewMockUserDao(mockCtrl)

	// step2.  Definition mock The concrete execution logic of 
	// 1. Parameter support Eq,Any,Not,Nil
	//Eq(value)  To express with  value  Equivalent value .
	//Any()  Can be used to represent any input parameter .
	//Not(value)  Used to indicate non  value  Value beyond .
	//Nil()  Express  None  value 
	//
	// 2.mock The number of method calls is supported as follows 
	//Times()  Assertion  Mock  The number of times the method was called .
	//MaxTimes()  Maximum number of times .
	//MinTimes()  The minimum number of times .
	//AnyTimes()  Any number of times ( Include  0  Time )
	//
	// 3. Return value support 
	// Return  Returns the determined value 
	// Do Mock  Method is called , What to do , Ignore return value .
	// DoAndReturn  You can dynamically control the return value .
	c1 := mockObj.EXPECT().Update("001", "ggr", "10010").Return(int64(1))
	c2 := mockObj.EXPECT().Update("001", "ggr", gomock.Any()).Return(int64(1))
	mockObj.EXPECT().Add("", "1001").Return(int64(0), errors.New("name is invalid")).AnyTimes()
	mockObj.EXPECT().Add("1001", gomock.Not("1001")).Return(int64(0), errors.New("phone_number is invalid")).MinTimes(1)
	mockObj.EXPECT().Add(gomock.Eq("1001"), "1001").Return(int64(0), errors.New("name is empty")).Times(1)
	mockObj.EXPECT().Select(gomock.Any()).Return(int64(1)).MaxTimes(2)
	mockObj.EXPECT().Update2(gomock.Any()).Return(int64(1)).Times(2)

	mockObj.EXPECT().Delete("1001").Do(func(i string) {
		t.Log("delete id=1001")
	})

	mockObj.EXPECT().Delete(gomock.Not("1001")).DoAndReturn(func(i string) int64 {
		return int64(1)
	})

	// step3.  Limit stub The call order of the function , If the order is inconsistent , False report 
	gomock.InOrder(c1, c2)

	// step4.  Test verification 
	ret1 := mockObj.Update("001", "ggr", "10010")
	ret2 := mockObj.Update("001", "ggr", "10020")
	ret3 := mockObj.Update2("1", "")
	ret4 := mockObj.Update2("")
	ret5 := mockObj.Select("")
	ret6, err1 := mockObj.Add("1001", "1001")
	ret7, err2 := mockObj.Add("1001", "1002")
	ret8 := mockObj.Delete("1001")
	ret9 := mockObj.Delete("1002")

	// step5.  Assertion 
	assert.Equal(t, ret1, int64(1))
	assert.Equal(t, ret2, int64(1))
	assert.Equal(t, ret3, int64(1))
	assert.Equal(t, ret4, int64(1))
	assert.Equal(t, ret5, int64(1))
	assert.Equal(t, ret6, int64(0))
	assert.Equal(t, ret7, int64(0))
	assert.Equal(t, ret8, int64(0))
	assert.Equal(t, ret9, int64(1))
	assert.NotNil(t, err1)
	assert.NotEmpty(t, err2)
}

Customize mock The implementation mainly includes user-defined parameters , Custom return value , Customize mock Number of calls and order of calls .

(1) Custom parameters

Parameter support Eq,Any,Not,Nil, Represent the meaning of :

  • Eq(value) Used in scenarios with fixed parameters .
  • Any() For scenarios with arbitrary parameters .
  • Not(value) Used to indicate that the parameter is not value Other value scenarios .
  • Nil() Used to represent parameters None Value scenarios

(2) Custom return value

The return value supports the following :

  • Return The scenario used to return the determined value
  • Do For scenarios with no return value .
  • DoAndReturn Used to dynamically control the return value .

(3) Customize mock Call the number

mock The number of calls supports the following scenarios :

  • Times() Assertion Mock The number of times the method was called , Number of times .
  • MaxTimes() Maximum number of times .
  • MinTimes() The minimum number of times .
  • AnyTimes() Any number of times ( Include 0 Time )

(4) Customize mock Call to order

When there are multiple mock When calling each other , You can go through 2 How to define mock Order of execution :

  • Directly after the function After
  • Use gomock.InOrder Set execution order

Please refer to the official documentation for more usage :https://pkg.go.dev/github.com/golang/mock/gomock#pkg-examples

原网站

版权声明
本文为[Johns]所创,转载请带上原文链接,感谢
https://yzsam.com/2021/09/20210901012008630Q.html