pemrograman

Cara Membuat Unit Test Menggunakan Library Moq Pada Golang

Melakukan unit test dengan cara mocking ini biasanya digunakan jika sudah beberapa fungsi yang dilakukan dengan format interface sehingga kita bisa asumsikan jika memanggil fungsi interface tersebut kita meyakini bahwa harus menghasilkan program yang benar.

Saat ini untuk membuat mocking kita menggunakan library dari github.com/matryer/moq. Jika belum ada library tersebut kita bisa download terlebih dahulu dengan perintah dibawah ini.

$ go install github.com/matryer/moq@latest

Berikut kita akan coba membuat suatu project yang memiliki fungsi interface dibawah ini.

package main

import "fmt"

type User struct {
	Username string `json:"username"`
	Password string `json:"password"`
}

//go:generate moq -out main_mock_test.go . UserRepositoryInterface
type UserRepositoryInterface interface {
	GetAllUsers() ([]User, error)
}

type UserService struct {
	UserRepositoryInterface
}

func (s UserService) GetUser() ([]User, error) {
	users, _ := s.UserRepositoryInterface.GetAllUsers()
	for i := range users {
		users[i].Password = "*****"
	}
	return users, nil
}

type UserRepository struct{}

func (r UserRepository) GetAllUsers() ([]User, error) {
	users := []User{
		{"real", "real"},
		{"real2", "real2"},
	}
	return users, nil
}

func main() {
	repository := UserRepository{}
	service := UserService{repository}
	users, _ := service.GetUser()
	fmt.Println(users)
}

Lalu lanjut dengan cara membuat unit test bisa dilihat dibawah ini

package main

import (
	"fmt"
	"reflect"
	"testing"

	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/mock"
)

type UserRepositoryMock struct {
	mock.Mock
}

func (r UserRepositoryMock) GetAllUsers() ([]User, error) {
	args := r.Called()
	users := []User{
		{"mock", "*****"},
	}
	return users, args.Error(1)
}

func TestService_GetUser(t *testing.T) {
	repository := UserRepositoryMock{}
	repository.On("GetAllUsers").Return([]User{}, nil)

	service := UserService{repository}
	users, _ := service.GetUser()
	for i := range users {
		assert.Equal(t, users[i].Password, "*****", "user password must be encrypted")
	}
	fmt.Println(users)
}

func TestUserService_GetUser(t *testing.T) {
	type fields struct {
		UserRepositoryInterface UserRepositoryInterface
	}
	tests := []struct {
		name    string
		fields  fields
		want    []User
		wantErr bool
	}{
		{
			name: "case ambil data user",
			fields: fields{
				UserRepositoryInterface: UserRepositoryMock{},
			},
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			s := UserService{
				UserRepositoryInterface: tt.fields.UserRepositoryInterface,
			}
			got, err := s.GetUser()
			if (err != nil) != tt.wantErr {
				t.Errorf("UserService.GetUser() error = %v, wantErr %v", err, tt.wantErr)
				return
			}
			if !reflect.DeepEqual(got, tt.want) {
				t.Errorf("UserService.GetUser() = %v, want %v", got, tt.want)
			}
		})
	}
}
comments powered by Disqus