2017-09-15 81 views
0

我試圖測試一個從Go中的請求中檢索Cookie的函數,但即使它們具有相同的值,比較失敗。測試從函數返回的Cookie

package main 

import (
    "fmt" 
    "log" 
    "net/http" 
    "net/http/httptest" 
    "reflect" 
) 

func GetCookie(url string) *http.Cookie { 
    req, err := http.NewRequest("GET", url, nil) 
    req.Header.Set("Content-Type", "application/x-www-form-urlencoded") 

    client := http.DefaultClient 

    res, err := client.Do(req) 
    if err != nil { 
     panic(err) 
    } 
    defer res.Body.Close() 

    cookies := res.Cookies() 
    var mycookie *http.Cookie 
    for _, c := range cookies { 
     if c.Name == "mycookie" { 
      mycookie = c 
     } 
    } 

    return mycookie 
} 

func main() { 
    validCookie := &http.Cookie{ 
     Name:  "mycookie", 
     Value: "SomeValue", 
     Path:  "/mysite", 
     HttpOnly: true, 
     Secure: true, 
    } 

    ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 
     http.SetCookie(w, validCookie) 
     w.Header().Set("Content-Type", "text/plain") 
     w.WriteHeader(200) 
    })) 
    defer ts.Close() 

    fmt.Printf("EqualL Cookies: %t\n", reflect.DeepEqual(validCookie, validCookie)) 

    if got := GetCookie(ts.URL); !reflect.DeepEqual(got, validCookie) { 
     log.Fatalf("NOT THE SAME\n got = '%v'\nwant = '%v'", got, validCookie) 
    } 
} 

遊樂場鏈接:https://play.golang.org/p/T4dbZycMuT

我已經檢查了DeepEqual函數的文檔,從我能看到2個結構/指針應該是相同的(特別是考慮到cookie沒有不導出字段)。

我可以更改函數來比較Cookie字符串,但是我想知道是否有簡單的解釋爲什麼這不起作用或者是由於文檔指定的「不一致性」。 也有任何方法來測試結構,而不是在這個情況下的字符串表示(或者我犯了一個錯誤,也許)?

回答

3

reflect.DeepEquals比較餅乾是一個非常糟糕的主意。 http.Cookie type包含的組件不會轉換成cookie的文字標題表示,具體取決於它如何被解析和/或操作。

如果你改變你的代碼使用%#v

if got := GetCookie(ts.URL); !reflect.DeepEqual(got, validCookie) { 
    log.Fatalf("NOT THE SAME\n got = '%#v'\nwant = '%#v'", got, validCookie) 
} 

...你會看到其中的差別:

EqualL Cookies: true 
2009/11/10 23:00:00 NOT THE SAME 
got = '&http.Cookie{Name:"mycookie", Value:"SomeValue", Path:"/mysite", Domain:"", Expires:time.Time{wall:0x0, ext:0, loc:(*time.Location)(nil)}, RawExpires:"", MaxAge:0, Secure:true, HttpOnly:true, Raw:"mycookie=SomeValue; Path=/mysite; HttpOnly; Secure", Unparsed:[]string(nil)}' 
want = '&http.Cookie{Name:"mycookie", Value:"SomeValue", Path:"/mysite", Domain:"", Expires:time.Time{wall:0x0, ext:0, loc:(*time.Location)(nil)}, RawExpires:"", MaxAge:0, Secure:true, HttpOnly:true, Raw:"", Unparsed:[]string(nil)}' 

相反,只是直接比較URL字符串:

if got := GetCookie(ts.URL); got.String() == validCookie.String() { 
3

使用fmt.Printf("%#v")顯示問題:

got=  &http.Cookie{Name:"mycookie", Value:"SomeValue", Path:"/mysite", Domain:"", Expires:time.Time{wall:0x0, ext:0, loc:(*time.Location)(nil)}, RawExpires:"", MaxAge:0, Secure:true, HttpOnly:true, Raw:"mycookie=SomeValue; Path=/mysite; HttpOnly; Secure", Unparsed:[]string(nil)} 
validCookie=&http.Cookie{Name:"mycookie", Value:"SomeValue", Path:"/mysite", Domain:"", Expires:time.Time{wall:0x0, ext:0, loc:(*time.Location)(nil)}, RawExpires:"", MaxAge:0, Secure:true, HttpOnly:true, Raw:"", Unparsed:[]string(nil)} 

解析cookie的值Raw填充,而構建的cookie沒有Raw值,可以理解。

遊樂場:https://play.golang.org/p/ghzkjUoEGW