Skip to content
Santekno.com | Level Up Your Engineering Skills
EN
📖 0%
29 Nov 2022 · 7 min read ·Article 22 / 119
Go

How to Create Integration Tests in Golang

IH
Ihsan Arif
Writer at Santekno · Backend Engineer

Carrying out integration tests for APIs means that we must at least be able to run the application first so that integrated testing can be carried out. We need to prepare several cases, test cases that cover the needs of the integration test. For example, the API Endpoint' that we have worked on has a database, cache` or other external resource that is related to the continuity of the API Endpoint.

So, we will simulate how to carry out an API integration test. The first stage is that we create an API Service where the API is used for number addition operations.

Create API Programs

The following is the API Endpoint program that will be tested or an integration test will be created.

go
 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}

In this program there are several validations when the program is run, namely * The parameters entered must be integer

  • Do not fill in the parameters a and b then it will become
  • Test if it doesn’t send authToken

After the above program is complete, we run it with the command

bash
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'

If the program has run successfully, it will be visible or can be accessed using postman and curl with endpoint and port :9000.

bash
1➜  materi curl 'http://localhost:9000/add?a=2&b=2&authtoken=abcdef123'
2{
3 "result": 4
4}%   

If the program is successful as above then, we have run the API program to add numbers using the http protocol.

Create Integration Tests

Next, we will create an API integration test that we created earlier with several cases mentioned above.

Prepare the program or file main.go to create API Testing.

go
 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}

We will use the APISum method to access the http API that we have created as the main server which we will test using this integration test.

Create Client Struct

Create a struct for the API structure and response like this.

go
1type MathClient struct {
2	Token string
3	Host  string
4}
5
6type AddResult struct {
7	Result int `json:"result"`
8}

Create a Sum API Access Method

then we will create a method to retrieve the API sum data.

go
 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}

Create a Unit Test which is used as an Integration Test

Next, we will create this API Integration testing in this method. We can make a program like this or just generate in the APISum method.

go
 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}

Add Test Cases

Then, so that we can carry out case by case testing, we need to fill in the number of cases in the curly brackets above with contents like this.

go
 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},

Run Integration Test

Everything has been completed for testing and creating tests. Don’t forget that because this is integration test code, we need to add something so that when we do go test -v we can add the code above like this.

go
1//go:build integration

We continue by running go test with the integration parameter

bash
1$ go test -v -tags=integration

Also make sure the API Endpoint program is running

bash
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'

Related Articles

💬 Comments