Unit test
If it's difficult to write the test, you might consider to break down the function into pieces.
Initialize before test
If it need to initalize first like connecting database, we can create a main_test.go
then wrote this below.
func TestMain(m *testing.M) {
initializer.Initialize()
code := m.Run()
os.Exit(code)
}
Testing the route
If we want to testing route which used gin. We can create a router, then use httptest.NewRecorder()
to test this route.
//set a router
router := gin.Default()
router.POST("/register", controller.Register)
//create a request with a body with JSON
user := model.User{
ID: "test",
Email: "test@example.com",
Password: "123456",
}
requestBody, _ := json.Marshal(user)
req, _ := http.NewRequest("POST", "/register", bytes.NewBuffer(requestBody))
// Set the header
req.Header.Set("Content-Type", "application/json")
//Recorder
recorder := httptest.NewRecorder()
router.ServeHTTP(recorder, req)
Remember that if the route is for register or something, you need to delete the test data after the test.
Example for Unit test
Simple test
func TestVerifyToken(t *testing.T) {
token := "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJJRCI6InRlc3QiLCJFbWFpbCI6InRlc3RAZXhhbXBsZS5jb20ifQ.F8jgR95R3FAs6L1Cn4-eZpLv7N2tKJ7r5VmuqBDYD6k"
secretKey := []byte("test-key")
result, err := helper.VerifyToken(token, secretKey)
if err != nil {
t.Errorf("expect no error, but got %v", err)
}
if !result.Valid {
t.Errorf("expect result is valided")
}
claims, ok := result.Claims.(jwt.MapClaims)
if !ok {
t.Errorf("expect result claims to be MapClaims")
}
if claims["Email"] != "test@example.com" {
t.Errorf("expect result Email to be test@example.com")
}
if claims["ID"] != "test" {
t.Errorf("expect result ID to be test")
}
}
Route test
func TestUserRegister(t *testing.T) {
//set a router
router := gin.Default()
router.POST("/register", controller.UserRegister)
//create a request with a body with JSON
user := model.User{
ID: "test",
Email: "test@example.com",
Password: "123456",
}
requestBody, _ := json.Marshal(user)
req, _ := http.NewRequest("POST", "/register", bytes.NewBuffer(requestBody))
req.Header.Set("Content-Type", "application/json")
recorder := httptest.NewRecorder()
router.ServeHTTP(recorder, req)
// Check the status code is what we expect.
if status := recorder.Code; status != http.StatusOK {
t.Errorf("handler returned wrong status code: got %v want %v",
status, http.StatusOK)
}
// Check the response body is what we expect.
expectedResponse := `{"message":"User registered"}`
if recorder.Body.String() != expectedResponse {
t.Errorf("handler returned unexpected body: got %v want %v",
recorder.Body.String(), expectedResponse)
}
//Remember that this function is for register. So we need to delete user after testing.
initializer.DB.Exec("DELETE FROM users WHERE id = 'test'")
}
Test with Redis
/**
* Test that is the token add into black list successfully
* Remember to delete the token from redis after the test is done
*/
func TestAddTokenToBlacklist(t *testing.T) {
token := "test token"
result := model.AddTokenToBlacklist(token)
if result != nil {
t.Errorf("expected no error, but got %v", result)
}
isExist, err := initializer.RDB.SIsMember(context.Background(), "black_list", token).Result()
if err != nil {
t.Errorf("expected no error, but got %v", err)
}
if isExist != true {
t.Errorf("expected %v, but got %v", true, isExist)
}
initializer.RDB.SRem(context.Background(), "black_list", token)
}