Case 1
/myapp/app_test.go
package myapp
import (
"encoding/json"
"io/ioutil"
"net/http"
"net/http/httptest"
"strings"
"testing"
"github.com/stretchr/testify/assert"
)
func TestIndexPathHandler(t *testing.T) {
assert := assert.New(t)
res := httptest.NewRecorder()
req := httptest.NewRequest("GET", "/", nil)
mux := NewHttpHandler()
mux.ServeHTTP(res, req)
assert.Equal(http.StatusOK, res.Code)
data, _ := ioutil.ReadAll(res.Body)
assert.Equal("Hello World", string(data))
}
func TestBarPathHandler_WithoutName(t *testing.T) {
assert := assert.New(t)
res := httptest.NewRecorder()
req := httptest.NewRequest("GET", "/bar", nil)
mux := NewHttpHandler()
mux.ServeHTTP(res, req)
assert.Equal(http.StatusOK, res.Code)
data, _ := ioutil.ReadAll(res.Body)
assert.Equal("Hello World!", string(data))
}
func TestBarPathHandler_WithName(t *testing.T) {
assert := assert.New(t)
res := httptest.NewRecorder()
req := httptest.NewRequest("GET", "/bar?name=tucker", nil)
mux := NewHttpHandler()
mux.ServeHTTP(res, req)
assert.Equal(http.StatusOK, res.Code)
data, _ := ioutil.ReadAll(res.Body)
assert.Equal("Hello tucker!", string(data))
}
func TestFooHandler_WithoutJson(t *testing.T) {//1)foo핸들러를 받아서 Json으로 변환
assert := assert.New(t)//시작하기전에 앞서서 //1-1goconvey를 실행시키고 작업을 해줘야한다.
res := httptest.NewRecorder()
req := httptest.NewRequest("GET", "/foo", nil)//2)입력값 없이 foo에 대해서 진행
mux := NewHttpHandler()
mux.ServeHTTP(res, req)
assert.Equal(http.StatusBadRequest, res.Code)//3)StatusOK->StatusBadRequest로 바꿔줘야한다.
}//4)goconvey가 백그라운드에서 검사를 해준다.
//5)여기서 부터는 JSON을 넣어서 한번 실습해본다.
func TestFooHandler_WithJson(t *testing.T) {
assert := assert.New(t)
res := httptest.NewRecorder()
req := httptest.NewRequest("POST", "/foo",
strings.NewReader(`{"first_name":"tucker", "last_name":"kim", "email":"tucker@naver.com"}`))
mux := NewHttpHandler()
mux.ServeHTTP(res, req)
assert.Equal(http.StatusCreated, res.Code)
//여기서 부터 user 구조체를 디코더 해주는 작업
user := new(User)
err := json.NewDecoder(res.Body).Decode(user)//에러 받기
assert.Nil(err)//에러가 없어야한다.
assert.Equal("tucker", user.FirstName)
assert.Equal("kim", user.LastName)
}
Go
복사
•
보충설명
•
1-1 : goconvey를 실행시키고 지금 할당된 포트(8080)를 접속하면 goconvey가 돌고 있는 것을 확인 할 수 있다.
/myapp/app.go
package myapp
import (
"encoding/json"
"fmt"
"net/http"
"time"
)
type User struct {
FirstName string `json:"first_name"`
LastName string `json:"last_name"`
Email string `json:"email"`
CreatedAt time.Time `json:"created_at"`
}
func indexHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, "Hello World")
}
type fooHandler struct{}
func (f *fooHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
user := new(User)
err := json.NewDecoder(r.Body).Decode(user)//json 디코딩이 실패할 경우 err가 나온다.
if err != nil {
w.WriteHeader(http.StatusBadRequest)
fmt.Fprint(w, "Bad Request: ", err)
return
}
user.CreatedAt = time.Now()
data, _ := json.Marshal(user)
w.Header().Add("content-type", "application/json")
w.WriteHeader(http.StatusCreated)
fmt.Fprint(w, string(data))
}
func barHandler(w http.ResponseWriter, r *http.Request) {
name := r.URL.Query().Get("name")
if name == "" {
name = "World"
}
fmt.Fprintf(w, "Hello %s!", name)
}
func NewHttpHandler() http.Handler {
mux := http.NewServeMux()
mux.HandleFunc("/", indexHandler)
mux.HandleFunc("/bar", barHandler)
mux.Handle("/foo", &fooHandler{})
return mux
}
Go
복사
/main.go
package main
import (
"net/http"
"github.com/GloryKim/Web_Go_Private/04_File upload/Number1/myapp"
)
func main() {
//http.Handle("/", http.FileServer(http.Dir("public"))) //이 경로의 파일을 오픈
http.ListenAndServe(":3000", myapp.NewHttpHandler())
}
Go
복사
Case 2
/public/index.html
<html>
<head>
<title>Go 로 만드는 웹 4</title>
</head>
<body>
<p><h1>파일을 전송해보자.</h1></p>
<form action="/uploads" method="POST" accept-charset="utf-8" enctype="multipart/form-data">
<p><input type="file" id="upload_file" name="upload_file"/></p>
<p><input type="submit" name="upload"/></p>
</form>
</body>
</html>
HTML
복사
/main_test.go
package main
import (
"bytes"
"io"
"mime/multipart"
"net/http"
"net/http/httptest"
"os"
"path/filepath"
"testing"
"github.com/stretchr/testify/assert"
)
func TestUploadTest(t *testing.T) {
assert := assert.New(t)
path := "C:/Users/tucker/Downloads/goWeb3.png"
file, _ := os.Open(path)
defer file.Close()
os.RemoveAll("./uploads")
buf := &bytes.Buffer{}
writer := multipart.NewWriter(buf)
multi, err := writer.CreateFormFile("upload_file", filepath.Base(path))
assert.NoError(err)
io.Copy(multi, file)
writer.Close()
res := httptest.NewRecorder()
req := httptest.NewRequest("POST", "/uploads", buf)
req.Header.Set("Content-type", writer.FormDataContentType())
uploadsHandler(res, req)
assert.Equal(http.StatusOK, res.Code)
uploadFilePath := "./uploads/" + filepath.Base(path)
_, err = os.Stat(uploadFilePath)
assert.NoError(err)
uploadFile, _ := os.Open(uploadFilePath)
originFile, _ := os.Open(path)
defer uploadFile.Close()
defer originFile.Close()
uploadData := []byte{}
originData := []byte{}
uploadFile.Read(uploadData)
originFile.Read(originData)
assert.Equal(originData, uploadData)
}
Go
복사
/main.go
package main
import (
"fmt"
"net/http"
"os"
"io"
)
func uploadsHandler(w http.ResponseWriter, r *http.Request) {
uploadFile, header, err := r.FormFile("upload_file")
if err != nil {
w.WriteHeader(http.StatusBadRequest)
fmt.Fprint(w, err)
return
}
defer uploadFile.Close()
dirname := "./uploads"
os.MkdirAll(dirname, 0777)
filepath := fmt.Sprintf("%s/%s", dirname, header.Filename)
file, err := os.Create(filepath)
defer file.Close() //항상 닫아줘야한다.핸들이 OS 자원인데 꼭 반납을 해줘야하기 때문
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
fmt.Fprint(w, err)
return
}
io.Copy(file, uploadFile)//File Copy os.Copy가 아닌거 검토
w.WriteHeader(http.StatusOK)
fmt.Fprint(w, filepath)
}
func main() {
http.HandleFunc("/uploads", uploadsHandler)
http.Handle("/", http.FileServer(http.Dir("public")))
http.ListenAndServe(":3000", nil)
}
Go
복사