Skip to content

Commit

Permalink
Google工程师讲解Go:接口测试及服务器测试
Browse files Browse the repository at this point in the history
  • Loading branch information
rehth committed Jul 12, 2019
1 parent c80ad38 commit c9daf29
Show file tree
Hide file tree
Showing 5 changed files with 199 additions and 14 deletions.
87 changes: 87 additions & 0 deletions GoogleGo/errhandling/server/errWrapper_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package main

import (
"errors"
"fmt"
"io/ioutil"
"net/http"
"net/http/httptest"
"os"
"strings"
"testing"

"goLearn/GoogleGo/errhandling/server/fileHandler"
)

func errPanic(writer http.ResponseWriter, request *http.Request) error {
panic(123)
}

func errUserError(writer http.ResponseWriter, request *http.Request) error {
return fileHandler.UserError("User Error")
}

func errNotFound(writer http.ResponseWriter, request *http.Request) error {
return os.ErrNotExist
}

func errNoPermission(writer http.ResponseWriter, request *http.Request) error {
return os.ErrPermission
}

func errUnknown(writer http.ResponseWriter, request *http.Request) error {
return errors.New("unKnown Error")
}

func noError(writer http.ResponseWriter, request *http.Request) error {
fmt.Fprintln(writer, "No Error")
return nil
}

func verifyResponse(response *http.Response, code int, msg string, t *testing.T) {
b, _ := ioutil.ReadAll(response.Body)
body := strings.Trim(string(b), "\n")
if response.StatusCode != code {
t.Errorf("expect (%d, %s); got (%d %s)\n", code, msg, response.StatusCode, body)
}

}

// 表格驱动测试
var data = []struct {
handler appHandler
code int
msg string
}{
{errPanic, 500, "Internal Server Error"},
{errNotFound, 404, "Not Found"},
{errNoPermission, 403, "Forbidden"},
{errUnknown, 500, "Internal Server Error"},
{errUserError, 400, "User Error"},
{noError, 200, "No Error"},
}

// 直接调用函数,使用假的 Request/Response
func TestErrWrapper(t *testing.T) {
for _, d := range data {
handler := errWrapper(d.handler)
request := httptest.NewRequest(http.MethodGet, "localhost:8888", nil)
response := httptest.NewRecorder()
handler(response, request)

verifyResponse(response.Result(), d.code, d.msg, t)
}
}

// 启动一个server,使用http请求
func TestErrWrapperInServer(t *testing.T) {
for _, d := range data {
handler := http.HandlerFunc(errWrapper(d.handler))
server := httptest.NewServer(handler)

response, _ := http.Get(server.URL)

verifyResponse(response, d.code, d.msg, t)

}
}
2 changes: 1 addition & 1 deletion GoogleGo/errhandling/server/fileHandler/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ func (e UserError) Error() string {
}

func Handler(writer http.ResponseWriter, request *http.Request) error {
if strings.Index(request.URL.Path, Prefix) != 0 {
if strings.HasPrefix(request.URL.Path, Prefix) {
return UserError("path must start with " + Prefix)
}
path := request.URL.Path[len(Prefix):]
Expand Down
24 changes: 11 additions & 13 deletions GoogleGo/errhandling/server/web.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,21 +26,19 @@ func errWrapper(handler appHandler) func(http.ResponseWriter, *http.Request) {
err := handler(writer, request)
if err != nil {
log.Println("Error handling request:", err.Error())
code := http.StatusOK

switch err.(type) {
case *os.PathError:
if os.IsNotExist(err) {
code = http.StatusNotFound
} else if os.IsPermission(err) {
code = http.StatusForbidden
} else {
code = http.StatusBadRequest
}

case fileHandler.UserError:
http.Error(writer, err.Error(), http.StatusBadRequest)
if e, ok := err.(fileHandler.UserError); ok {
http.Error(writer, e.Error(), http.StatusBadRequest)
return
}

code := http.StatusOK

switch {
case os.IsNotExist(err):
code = http.StatusNotFound
case os.IsPermission(err):
code = http.StatusForbidden
default:
code = http.StatusInternalServerError
}
Expand Down
54 changes: 54 additions & 0 deletions GoogleGo/testing/subStr.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package main

import "fmt"

func lengthOfNonRepeatingSubStr(s string) int {
start, maxLength := 0, 0
lastOccurred := make(map[rune]int)

for ind, c := range []rune(s) {
if last, ok := lastOccurred[c]; ok && last >= start {
start = last + 1
}
if ind-start+1 > maxLength {
maxLength = ind - start + 1
}
lastOccurred[c] = ind
}
return maxLength
}

func main() {
// 除了 slice, map, function 的内建类型都可作为key
m1 := map[string]int{
"a": 1,
"b": 2,
"c": 3,
}
m2 := make(map[string]string) // m2 is empty map

var m3 map[string]float64 // m3 is nil

fmt.Println(m1, m2, m3)

fmt.Println("Traversing map")
for key, value := range m1 {
fmt.Println(key, value)
}

fmt.Println("Getting values")
a := m1["a"]
d, ok := m1["d"]
fmt.Println(a, d, ok)

fmt.Println("Deleting values")
delete(m1, "c")
fmt.Println(m1)

fmt.Println(lengthOfNonRepeatingSubStr(""))
fmt.Println(lengthOfNonRepeatingSubStr("a"))
fmt.Println(lengthOfNonRepeatingSubStr("abc"))
fmt.Println(lengthOfNonRepeatingSubStr("abcabc"))
fmt.Println(lengthOfNonRepeatingSubStr("这是在学习Golang"))
fmt.Println(lengthOfNonRepeatingSubStr("一二三二一"))
}
46 changes: 46 additions & 0 deletions GoogleGo/testing/subStr_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package main

import "testing"

func TestSubstr(t *testing.T) {
tests := []struct {
s string
ans int
}{
// Normal cases
{"abcabcbb", 3},
{"pwwkew", 3},

// Edge cases
{"", 0},
{"b", 1},
{"bbbbbb", 1},
{"abcabcabcd", 4},

// Chinese support
{"这里是一个测试用例", 9},
{"一二三二一", 3},
{"这是在学习Golang", 11},
{"黑化肥发黑会发挥灰化肥会挥发", 7},
}

for _, s := range tests {
actual := lengthOfNonRepeatingSubStr(s.s)
if actual != s.ans {
t.Errorf("<func:lengthOfNonRepeatingSubStr>: args=%s, get=%d, expected=%d", s.s, actual, s.ans)
}
}
}

func BenchmarkSubstr(b *testing.B) {
s := "黑化肥发黑会发挥灰化肥会挥发"
ans := 7

b.ResetTimer()
for i := 0; i < b.N; i++ {
actual := lengthOfNonRepeatingSubStr(s)
if actual != ans {
b.Errorf("got %d for input %s; expected %d", actual, s, ans)
}
}
}

0 comments on commit c9daf29

Please sign in to comment.