GO Lang

GO_웹 제작(5)

u0jin 2020. 8. 13. 23:00

목표 : RESTful 코드 작성 ( DELETE ) &  테스트 코드 실행 

 

 

사용된 코드 :  main.go / app.go / app_test.go

 

순서대로 설명이 필요한 코드만 주석으로 설명하겠습니다.

 

< app_test .go >

  • func TestDeleteUser
func TestDeleteUser(t *testing.T) {

	assert := assert.New(t)

	ts := httptest.NewServer(NewHandler())
	defer ts.Close()

	req, _ := http.NewRequest("DELETE", ts.URL+"/users/1", nil)
	resp, err := http.DefaultClient.Do(req)
/*
	delete는 기본제공이 아니기 때문에 Do로 만들어야함
*/
	assert.NoError(err)
	assert.Equal(http.StatusOK, resp.StatusCode)

	data, _ := ioutil.ReadAll(resp.Body)
	log.Print(string(data))
}

 

log 패키지를 선언하고, test 결과값을 보면, No User Id가 나온다.

app.go에서 핸들러부분을 보면 그 이유를 알수 있다.

 

핸들러 변경전 결과값

 

< app.go >

  • func NewHandler() http.Handler 
func NewHandler() http.Handler {

	userMap = make(map[int]*User)
	lastID = 0

	mux := mux.NewRouter()

	mux.HandleFunc("/", indexHandler)
	mux.HandleFunc("/users", usersHandler).Methods("GET")
	mux.HandleFunc("/users", createUserHandler).Methods("POST")
    
	mux.HandleFunc("/users/{id:[0-9]+}", getUserInfoHandler).Methods("GET") 
/*
	Methods없이 그냥 돌리면 뭘 넣든 userInfo핸들러가 적용되기때문에,
    GET으로 요청이 들어온 경우에만 호출이 되도록 변경해줘야함
*/
 
	return mux
}

핸들러 변경후 결과값

 

핸들러를 GET 요청이 있을때만 응답하도록 변경하고 나면 에러가 뜨기 때문에, 

이제 새로 만들어줘야한다.

 

* 400번대 오류는 클라이언트 요청이 미리 정의된 파라미터 요구사항을 위반한 경우 발생한다.

 

< app.go >

  • func NewHandler() http.Handler 
func NewHandler() http.Handler {

	userMap = make(map[int]*User)
	lastID = 0

	mux := mux.NewRouter()

	mux.HandleFunc("/", indexHandler)
	mux.HandleFunc("/users", usersHandler).Methods("GET")
	mux.HandleFunc("/users", createUserHandler).Methods("POST")
	mux.HandleFunc("/users/{id:[0-9]+}", getUserInfoHandler).Methods("GET")
	mux.HandleFunc("/users/{id:[0-9]+}", deleteUserHandler).Methods("DELETE")
/*
	오류가 나지 않도록 delete함수도 선언해줘야함
*/

	return mux
}

 

  • func deleteUserHandler(w http.ResponseWriter, r *http.Request) 
func deleteUserHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
/*
	고릴라 먹스가 제공해줌 -> 추출가능
*/

	id, err := strconv.Atoi(vars["id"])
/*
	int 가 아닐수도 있기때문에 변환해줘야함
*/    
	if err != nil {
		w.WriteHeader(http.StatusBadRequest)
		fmt.Fprint(w, err)
		return
	}
	_, ok := userMap[id]
/*
	map에 데이터가 없는경우를 생각해줘야함
    등록을 한게 없는데 지우려고 할때, 문제가 되기때문에 체크할 필요가있음
*/
	if !ok {
		w.WriteHeader(http.StatusOK)
		fmt.Fprint(w, "No User ID:", id)
		return
	}
	

/*
	데이터가 있어서 지울것이 있는경우,
*/
	delete(userMap, id)
/*
	맵의 기능-> 키에 해당하는 맵을 삭제해줌
*/
	w.WriteHeader(http.StatusOK)
	fmt.Fprint(w, "Deleted User ID:", id)
}

 

핸들러 수정완료 후 결과값 

 

 

이제 다시 app_test.go 를 수정해서 test 코드를 완성하면 된다.

 

< app_test .go >

  • func TestDeleteUser
func TestDeleteUser(t *testing.T) {

	assert := assert.New(t)

	ts := httptest.NewServer(NewHandler())
	defer ts.Close()

	req, _ := http.NewRequest("DELETE", ts.URL+"/users/1", nil)
	resp, err := http.DefaultClient.Do(req)
	//delete 는 없기때문에 Do로 해야함 

	assert.NoError(err)
	assert.Equal(http.StatusOK, resp.StatusCode)


/*
	핸들러를 만들때마다 맵을 새로만들기 때문에 사실 기존에 등록했던 유저들은 다 지워짐
    다시말해, 지울게없어야 맞는거임
*/

// 지울게 없었다라는 메세지가 와야함 
	data, _ := ioutil.ReadAll(resp.Body)
	assert.Contains(string(data), "No User ID:1")

	// 유저를 등록하는 코드
	resp, err = http.Post(ts.URL+"/users", "application/json",
		strings.NewReader(`{"first_name":"ujin", "last_name":"kim", "email":"yujin@naver.com"}`))
	assert.NoError(err)
	assert.Equal(http.StatusCreated, resp.StatusCode)


	// 아이디를 알아오는 코드
	user := new(User)
	err = json.NewDecoder(resp.Body).Decode(user)
	assert.NoError(err)
	assert.NotEqual(0, user.ID)

	// 그 아이디에 해당하는애 삭제하는 코드
	req, _ = http.NewRequest("DELETE", ts.URL+"/users/1", nil)
	resp, err = http.DefaultClient.Do(req)
	assert.NoError(err)
	assert.Equal(http.StatusOK, resp.StatusCode)
	data, _ = ioutil.ReadAll(resp.Body)
	assert.Contains(string(data), "Deleted User ID:1")

}

 


주석이 없는 코드는 아래의 사이트 - restful api 파일에 존재합니다.

github.com/u0jin/Go_Website_first.git