2017-09-15 8 views
0

Je tente de tester une fonction qui récupère un cookie à partir d'une requête dans Go. Toutefois, même s'ils ont la même valeur, la comparaison échoue.Test du cookie renvoyé par la fonction dans Go

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) 
    } 
} 

lien Playground: https://play.golang.org/p/T4dbZycMuT

J'ai vérifié la documentation sur la fonction DeepEqual et de ce que je peux voir les 2 struct/pointeur doit être la même (spécialement étant donné que Cookie n'a pas de champ non exportées).

Je peux changer la fonction pour comparer les chaînes de cookie mais je voudrais savoir s'il y a une explication simple pourquoi ceci ne fonctionne pas ou est-ce dû à "l'incohérence" comme la documentation spécifie. Existe-t-il un moyen de tester la structure plutôt que la représentation sous forme de chaîne dans ce scénario (Ou est-ce que j'ai fait une erreur peut-être)?

Répondre

3

Cookies avec reflect.DeepEquals Comparer est une très mauvaise idée. Le http.Cookie type contient des composants qui ne se traduisent pas dans la représentation d'en-tête littérale du cookie, en fonction de la façon dont il est analysé et/ou manipulé.

Si vous modifiez votre code pour utiliser %#v:

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

... vous verrez la différence:

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)}' 

Au lieu de cela, il suffit de comparer les chaînes d'URL directement:

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

L'utilisation fmt.Printf("%#v") montre la question:

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)} 

La valeur Raw du cookie est rempli analysable, alors que le cookie construit n'a pas de valeur Raw, compréhensible.

Playground: https://play.golang.org/p/ghzkjUoEGW