Cara Membuat Integration Test Pada Golang
Melakukan integration test untuk API setidaknya kita harus bisa menjalankan aplikasi-nya terlebih dahulu agar bisa dilakukan pengetesan secara terintegrasi.
Hal ini perlu kita siapkan beberapa case, test case yang mencakup kebutuhan dari integration Test tersebut. Misalkan dari API Endpoint kita yang sudah dikerjakan itu memiliki resource database, cache ataupun eksternal lain yang berhubungan dengan keberlangsungannya suatu API Endpoint tersebut.
Maka, kita akan simulasikan bagaimana cara melakukan integration test API. Tahapan yang pertama yaitu kita buat API Service yang mana API tersebut digunakan untuk operasi penjumlahan angka.
Membuat Program API
Berikut program API Endpoint yang akan diuji atau dibuat integration test-nya.
1package main
2
3import (
4 "encoding/json"
5 "fmt"
6 "net/http"
7 "strconv"
8)
9
10func main() {
11 http.HandleFunc("/add", HandleAddInts)
12 address := ":9000"
13 fmt.Printf("Memulai server at %s\n", address)
14 fmt.Println()
15 fmt.Println("contoh query: /add?a=2&b=2&authtoken=abcdef123")
16 fmt.Println("tokennya adalah 'abcdef123'")
17 err := http.ListenAndServe(address, nil)
18 if err != nil {
19 fmt.Printf("error ketika start server: %v", err)
20 }
21}
22
23type TambahResponse struct {
24 Result int `json:"result"`
25}
26
27func HandleAddInts(w http.ResponseWriter, r *http.Request) {
28 params := r.URL.Query()
29 paramA := params.Get("a")
30 paramB := params.Get("b")
31 token := params.Get("authtoken")
32
33 if paramA == "" || paramB == "" || token == "" {
34 http.Error(w, "tidak ada parameters", http.StatusBadRequest)
35 return
36 }
37
38 if token != "abcdef123" {
39 http.Error(w, "token tidak valid", http.StatusUnauthorized)
40 return
41 }
42
43 intA, err := strconv.Atoi(paramA)
44 if err != nil {
45 http.Error(w, "parameter 'a' harus integer", http.StatusBadRequest)
46 return
47 }
48
49 intB, err := strconv.Atoi(paramB)
50 if err != nil {
51 http.Error(w, "parameter 'b' harus integer", http.StatusBadRequest)
52 return
53 }
54
55 response := TambahResponse{
56 Result: intA + intB,
57 }
58
59 json, err := json.MarshalIndent(&response, "", " ")
60 if err != nil {
61 http.Error(w, "error while marshalling", http.StatusInternalServerError)
62 return
63 }
64
65 fmt.Fprint(w, string(json))
66}integer- Tidak mengisi parameter
adanbmaka akan menjadi - Mengujian jika tidak mengirimkan
authToken
Setelah program diatas selesai maka kita jalankan dengan perintah
1➜ integration-test git:(main) ✗ go run app/main.go
2Memulai server at :9000
3
4contoh query: /add?a=2&b=2&authtoken=abcdef123
5tokennya adalah 'abcdef123'curl dengan endpoint dan port :9000.1➜ materi curl 'http://localhost:9000/add?a=2&b=2&authtoken=abcdef123'
2{
3 "result": 4
4}% Jika program berhasil seperti diatas maka, kita sudah menjalankan program API untuk menambah angka menggunakan protokol http.
Membuat Test Integration
Selanjutnya, kita kan membuat test integration API yg tadi sudah kita buat itu dengan beberapa case yang sudah disebutkan diatas.
Siapkan program atau file main.go untuk membuat API Testing.
1package integrationtest
2
3import (
4 "encoding/json"
5 "fmt"
6 "io/ioutil"
7 "net/http"
8)
9
10type MathClient struct {
11 Token string
12 Host string
13}
14
15type AddResult struct {
16 Result int `json:"result"`
17}
18
19func (c *MathClient) APISum(i, j int) (int, error) {
20 query := fmt.Sprintf("http://%s/add?a=%v&b=%v&authtoken=%v", c.Host, i, j, c.Token)
21
22 response, err := http.Get(query)
23 if err != nil {
24 return 0, err
25 }
26 defer response.Body.Close()
27
28 data, err := ioutil.ReadAll(response.Body)
29 if err != nil {
30 return 0, err
31 }
32
33 a := AddResult{}
34 err = json.Unmarshal(data, &a)
35 if err != nil {
36 return 0, err
37 }
38
39 return a.Result, nil
40}Method APISum ini akan kita gunakan untuk mengakses http API yang sudah kita buat sebagai main server yang akan kita test menggunakan integration test ini.
Membuat Struct Client
Buat struct untuk struktur API dan responsenya seperti ini.
1type MathClient struct {
2 Token string
3 Host string
4}
5
6type AddResult struct {
7 Result int `json:"result"`
8}Membuat Method Akses API Sum
lalu kita akan buat method untuk ambil data penjumlahan API.
1func (c *MathClient) APISum(i, j string) (int, int, error) {
2 query := fmt.Sprintf("http://%s/add?a=%s&b=%s&authtoken=%v", c.Host, i, j, c.Token)
3
4 var statusCode int = http.StatusBadRequest
5 response, err := http.Get(query)
6 if err != nil {
7 return 0, statusCode, err
8 }
9 defer response.Body.Close()
10 statusCode = response.StatusCode
11 data, err := ioutil.ReadAll(response.Body)
12 if err != nil {
13 return 0, statusCode, err
14 }
15
16 a := AddResult{}
17 err = json.Unmarshal(data, &a)
18 if err != nil {
19 return 0, statusCode, err
20 }
21
22 return a.Result, statusCode, nil
23}Membuat Unit Test yang dijadikan Integration Test
Selanjutnya, kita akan membuat API Integration testing ini di method yang ini. Bisa kita buat program seperti ini atau generate saja pada method APISum.
1func TestMathClient_APISum(t *testing.T) {
2 type fields struct {
3 Token string
4 Host string
5 }
6 type args struct {
7 i string
8 j string
9 }
10 tests := []struct {
11 name string
12 fields fields
13 args args
14 want int
15 wantErr bool
16 wantCode int
17 }{
18 // testing test case
19 }
20 for _, tt := range tests {
21 t.Run(tt.name, func(t *testing.T) {
22 c := &MathClient{
23 Token: tt.fields.Token,
24 Host: tt.fields.Host,
25 }
26 got, gotCode, err := c.APISum(tt.args.i, tt.args.j)
27 if (err != nil) != tt.wantErr {
28 t.Errorf("MathClient.APISum() error = %v, wantErr %v", err, tt.wantErr)
29 return
30 }
31 if got != tt.want {
32 t.Errorf("MathClient.APISum() = %v, want %v", gotCode, tt.wantCode)
33 }
34 if gotCode != tt.wantCode {
35 t.Errorf("MathClient.APISum() = %v, want %v", gotCode, tt.wantCode)
36 }
37 })
38 }
39}Tambahkan Test Case
Lalu agar kita bisa melakukan pengujian case by case kita perlu isi berapa tesitng case pada kurung kurawal diatas dengan isi seperti ini.
1{
2 name: "case sukses jumlah data",
3 fields: fields{
4 Token: "abcdef123",
5 Host: "localhost:9000",
6 },
7 args: args{
8 i: "2",
9 j: "2",
10 },
11 want: 4,
12 wantErr: false,
13 wantCode: http.StatusOK,
14},
15{
16 name: "token tidak diset",
17 fields: fields{
18 Token: "abc",
19 Host: "localhost:9000",
20 },
21 args: args{
22 i: "2",
23 j: "2",
24 },
25 want: 0,
26 wantErr: true,
27 wantCode: http.StatusUnauthorized,
28},
29{
30 name: "host tidak sesuai",
31 fields: fields{
32 Token: "abcdef123",
33 Host: "localhost:500",
34 },
35 args: args{
36 i: "2",
37 j: "2",
38 },
39 want: 0,
40 wantErr: true,
41 wantCode: http.StatusBadRequest,
42},
43{
44 name: "case parameter kosong",
45 fields: fields{
46 Token: "abcdef123",
47 Host: "localhost:9000",
48 },
49 args: args{
50 i: "",
51 j: "",
52 },
53 want: 0,
54 wantErr: true,
55 wantCode: http.StatusBadRequest,
56},
57{
58 name: "case parameter bukan integer",
59 fields: fields{
60 Token: "abcdef123",
61 Host: "localhost:9000",
62 },
63 args: args{
64 i: "a",
65 j: "a",
66 },
67 want: 0,
68 wantErr: true,
69 wantCode: http.StatusBadRequest,
70},Jalankan Integration Test
Semua sudah selesai untuk pengujian dan pembuatan testing jangan lupa karena ini adalah code integration test maka kita perlu ada penambahan agar saat melakukan go test -v bisa kita tambahkan code diatas seperti ini.
1//go:build integrationintegration1$ go test -v -tags=integration1➜ integration-test git:(main) ✗ go run app/main.go
2Memulai server at :9000
3
4contoh query: /add?a=2&b=2&authtoken=abcdef123
5tokennya adalah 'abcdef123'