Interface merupakan suatu tipe data yang berisi kumpulan definisi method (hanya definisi saja) dengan nama tertentu. Untuk default value dari interface adalah nil. Interface syaratnya harus method dan method syaratnya harus ada kepemilikan. Contoh untuk 2 method Greeting code di bawah ini merupakan method milik struct Account dan Customer. Method tersebut dapat ditampung dalam sebuah interface bernama CustomerInterface.
Contoh code 1
packagemainimport"fmt"typeCustomerInterfaceinterface {Greeting() string}typeAccountstruct { Name string Password string}typeCustomerstruct { Name string AccountID int}func (a Account) Greeting() string {return"Hi "+ a.Name}func (c Customer) Greeting() string {return"Welcome "+ c.Name}// function untuk menggunakan interface dari method beberapa struct.funcNewUser(customerInterface CustomerInterface) string {return customerInterface.Greeting()}funcmain() {// variabel yang memiliki method yang sama dengan CustomerInterface account1 :=Account{ Name: "Dana", Password: "Test123", } customer1 :=Customer{ Name: "Firman", AccountID: 1, } fmt.Println(NewUser(customer1)) fmt.Println(NewUser(account1))}
Di package lain semisal handler.go membutuhkan method CheckUserByName dan Create dari package repository. Package tersebut diinputkan melalui fungsi NewHandler dengan parameter repo bertipe interface.
Semisal ingin membuat unit test dari method Example di package handler yang memanggil method CheckUserByName dan Create. Kita perlu membuat mocking repository yang memiliki method mirip package repository menggunakan package testify/mock seperti dibawah ini.
repositorymock.go
packagerepositorymockimport ("github.com/stretchr/testify/mock")typeRepoMockstruct {mock.Mock}funcNewRepoMock() *RepoMock {return&RepoMock {}}func (r *random) CheckUserByName(username string) (isExist bool, err error) {// sebagai indikator parameter input diperoleh ret := m.Called(username)// get return isExist dari mock dengan type assertion isExist= ret.Get(0).(bool)if ret.Get(1) !=nil {// get return error dari mock dengan type assertion err = ret.Get(1).(error) }return}func (r *random) Create(username string, password string) (err error) {// sebagai indikator parameter input diperoleh ret := m.Called(username, password)if ret.Get(0) !=nil {// get return error dari mock dengan type assertion err = ret.Get(0).(error) }return}
Mocking-an di atas dapat dijadikan sebagai input di fungsi NewHandler di unit testing seperti code di bawah ini karena fungsi NewHandler menerima input repo dengan tipe interface Repositorier. Interface Repositorier memiliki 2 method yaitu CheckUserByName dan Create. Baik package repository atau repositorymock mempunyai fungsi NewRepository dan NewRepoMock yang mengembalikkan struct yang memiliki 2 method tersebut.
packageproductimport ("testing""go-rest-api/repositorymock""github.com/stretchr/testify/require")funcTestExample(t *testing.T) {// inputkan repoMock ke NewHandler repoMock := repository.NewRepoMock() handler :=NewHandler(repoMock)// panggil fungsi Example dari Handler err := handler.Example("member_01", "Test123")// jika tidak ada error, maka unit testing PASS require.NoError(t, err)}