Pular para o conteúdo principal

victorstein.dev

62/100 Dias de Golang - Testes - Mockgen

Table of Contents

# Testes - Mockgen

Vamos usar a lib gomock para gerar os mocks.

Vamos criar um projeto e instalar a lib:

go install go.uber.org/mock/mockgen@latest

Agora basta criar o nosso service/user_service.go.

package service

type UserService interface {
    GetUser(id int) (string, error)
    CreateUser(name string) error
}

E agora o comando mágico para gerar os mocks:

mockgen -source=./service/user_service.go -destination=./mocks/mock_user_service.go -package=mocks

Vai ser criado um arquivo mocks/mock_user_service.go

// Code generated by MockGen. DO NOT EDIT.
// Source: ./service/user_service.go
//
// Generated by this command:
//
//	mockgen -source=./service/user_service.go -destination=./mocks/mock_user_service.go -package=mocks
//

// Package mocks is a generated GoMock package.
package mocks

import (
	reflect "reflect"

	gomock "go.uber.org/mock/gomock"
)

// MockUserService is a mock of UserService interface.
type MockUserService struct {
	ctrl     *gomock.Controller
	recorder *MockUserServiceMockRecorder
	isgomock struct{}
}

// MockUserServiceMockRecorder is the mock recorder for MockUserService.
type MockUserServiceMockRecorder struct {
	mock *MockUserService
}

// NewMockUserService creates a new mock instance.
func NewMockUserService(ctrl *gomock.Controller) *MockUserService {
	mock := &MockUserService{ctrl: ctrl}
	mock.recorder = &MockUserServiceMockRecorder{mock}
	return mock
}

// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockUserService) EXPECT() *MockUserServiceMockRecorder {
	return m.recorder
}

// CreateUser mocks base method.
func (m *MockUserService) CreateUser(name string) error {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "CreateUser", name)
	ret0, _ := ret[0].(error)
	return ret0
}

// CreateUser indicates an expected call of CreateUser.
func (mr *MockUserServiceMockRecorder) CreateUser(name any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateUser", reflect.TypeOf((*MockUserService)(nil).CreateUser), name)
}

// GetUser mocks base method.
func (m *MockUserService) GetUser(id int) (string, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "GetUser", id)
	ret0, _ := ret[0].(string)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// GetUser indicates an expected call of GetUser.
func (mr *MockUserServiceMockRecorder) GetUser(id any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUser", reflect.TypeOf((*MockUserService)(nil).GetUser), id)
}

E depois basta escrever o teste para com o mock. Aqui a diferença vai ser a forma com que moldamos o comportamento do mock em relação ao testify. Veja a função mockUserService.EXPECT()

package service_test

import (
	"testing"

	"mocktestes2/mocks"

	"go.uber.org/mock/gomock"
)

func TestGetUser_Success(t *testing.T) {
	ctrl := gomock.NewController(t)
	defer ctrl.Finish()

	mockUserService := mocks.NewMockUserService(ctrl)
	mockUserService.EXPECT().GetUser(1).Return("John Doe", nil)

	name, err := mockUserService.GetUser(1)

	if err != nil {
		t.Errorf("Esperado nil, mas obteve %v", err)
	}

	if name != "John Doe" {
		t.Errorf("Esperado John Doe, mas obteve %v", name)
	}
}