[Go] Unit testing Go code

  • Vanilla Go includes Testing
  • A test is a file with suffix_test.go
  • You define functions with prefix Test and with an special signature receiving a *testing.T arguement
  • The function inside calls methods of T
  • You can create subtests as goroutines
  • You use the CLI with go test
  • TableDrivenTest Design Pattern
  • Fuzzing since 1.19

Fuzzing: Automated testing that manipulates inputs to find bugs. Go fuzzing uses coverage guidance to find failures and is valuable in detecting security exploits and vunlnerabilities.

 

Code:

查看代码
package api

import (
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"strings"

	"project/data"
)

const apiUrl = "https://cex.io/api/ticker/%s/USD"

// add * to struct in return type is a pattern
// because if you want to return nil from the function
// without *, it doesn't compile
func GetRate(currency string) (*data.Rate, error) {

	if len(currency) < 3 {
		return nil, fmt.Errorf("3 characteres minimu; %d received", len(currency))
	}

	upCurrency := strings.ToUpper(currency)
	res, err := http.Get(fmt.Sprintf(apiUrl, upCurrency))
	if err != nil {
		return nil, err
	}

	var cexResp CEXResponse
	if res.StatusCode == http.StatusOK {
		// Wait all stream have been readed
		bodyBytes, err := io.ReadAll(res.Body)
		if err != nil {
			return nil, err
		}


		errJson := json.Unmarshal(bodyBytes, &cexResp)
		if errJson != nil {
			return nil, errJson
		}
	} else {
		return nil, fmt.Errorf("status code received: %v", res.StatusCode)
	}

	rate := data.Rate{Currency: upCurrency, Price: float32(cexResp.Ask)}
	return &rate, nil
}

 

Test:

package api_test

import (
	"testing"

	"project/api"
)

func TestApiCallWithEmptyCurrency(t *testing.T) {
	_, err := api.GetRate("")
	if err == nil {
		t.Error("error was not found")
	}
}

 

posted @ 2024-02-06 22:16  Zhentiw  阅读(4)  评论(0编辑  收藏  举报