2013-10-16 12 views

Trả lời

15

Xem phần đầu của goroot/src/pkg/appengine/aetest/context.go (nguồn được cập nhật chưa được đăng tại https://code.google.com/p/appengine-go). Ngay từ cái nhìn đầu tiên, ứng dụng thử nghiệm mới có vẻ là phiên bản appenginetesting hơi beefier/khác nhau, do đó bạn có thể thực hiện các loại kiểm tra tương tự, xem here để biết cách thực hiện với cách sampleHandler (w http.ResponseWriter, r * http. Yêu cầu) được gọi.

Ngoài ra, bạn có thể làm cho ContextHandler của http.Handler của bạn giống như dưới đây:

type ContextHandler struct { 
    Real func(*appengine.Context, http.ResponseWriter, *http.Request) 
} 

func (f ContextHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { 
    c := appengine.NewContext(r) 
    f.Real(c, w, r) 
} 

func myNewHandler(c appengine.Context, w http.ResponseWriter, r *http.Request) { 
// do something 
} 

Sau đó, bạn có thể làm điều này trong init() để hỗ trợ sản xuất:

http.Handle("/myNewHandler", ContextHandler{myNewHandler}) 

Điều này làm cho thử nghiệm chức năng dễ dàng:

func TestMyNewHandler(t *testing.T) { 
    c := aetest.NewContext() 
    r, _ := http.NewRequest("GET", "/tasks/findOverdueSchedules", nil) 
    w := httptest.NewRecorder() 
    myNewHandler(c, w, r) 
    if 200 != w.Code { 
     t.Fail() 
    } 
} 

Đây là nội dung từ ngữ cảnh.go bên trong appengine/aetest:

/* Gói dịch vụ cung cấp một appengine.Có thể dùng để kiểm tra.

Một ví dụ kiểm tra file: gói foo_test

import (
    "testing" 

    "appengine/memcache" 
    "appengine/aetest" 
) 

func TestFoo(t *testing.T) { 
    c, err := aetest.NewContext(nil) 
    if err != nil { 
     t.Fatal(err) 
    } 
    defer c.Close() 

    it := &memcache.Item{ 
     Key: "some-key", 
     Value: []byte("some-value"), 
    } 
    err = memcache.Set(c, it) 
    if err != nil { 
     t.Fatalf("Set err: %v", err) 
    } 
    it, err = memcache.Get(c, "some-key") 
    if err != nil { 
     t.Fatalf("Get err: %v; want no error", err) 
    } 
    if g, w := string(it.Value), "some-value" ; g != w { 
     t.Errorf("retrieved Item.Value = %q, want %q", g, w) 
    } 
} 

Biến môi trường APPENGINE_API_SERVER xác định vị trí của api_server.py thực thi để sử dụng. Nếu không được đặt, hệ thống PATH sẽ được tư vấn. */

+0

Nó dường như không quá thanh lịch để có 'var contextCreator func (r * http.Request) appengine.Context = appengine.NewContext' (https://github.com/icub3d/appenginetesting/blob/master/recorder_test.go#L14) trong tất cả các trình xử lý mã không thử nghiệm. – Dan

+0

Dường như không có c: = appengine.NewContext (r) bên trong mỗi http.Handler. Tôi đã cập nhật bài đăng của mình để bao gồm cách tôi thực hiện. – mzimmerman

+0

Tôi đồng ý với bạn và điều này có vẻ như là một giải pháp tuyệt vời. Trong thực tế, tôi đang sử dụng Bộ công cụ Gorilla và tóm tắt ví dụ của bạn một chút để sử dụng ['github.com/gorilla/context'] (http://www.gorillatoolkit.org/pkg/context) cho phép tôi thêm tất cả các loại khác những thứ liên quan đến việc thiết lập yêu cầu. – Dan

1

Nếu bạn không phản đối việc sử dụng Martini, tiêm phụ thuộc là cách hay để giải quyết vấn đề. Đây là cách bạn có thể thiết lập thử nghiệm của bạn (với Ginkgo):

var _ = Describe("Items", func() { 

    var (
     m *martini.ClassicMartini 
    ) 

    BeforeEach(func() { 
     m = martini.Classic() 

     // injects app engine context into requests 
     m.Use(func(c martini.Context, req *http.Request) { 
      con, _ := aetest.NewContext(nil) 
      c.MapTo(con, (*appengine.Context)(nil)) 
     }) 

     m.Get("/items", func(c martini.Context){ 
      // code you want to test 
     }) 
    }) 

    It("should get items", func() { 
     recorder := httptest.NewRecorder() 
     r, _ := http.NewRequest("GET", "/items", nil) 
     m.ServeHTTP(recorder, r) // martini server used 
     Expect(recorder.Code).To(Equal(200)) 
    }) 
}) 

Trong sản xuất các bối cảnh thực tế sẽ được tiêm:

m.Use(func(c martini.Context, req *http.Request) { 
    c.MapTo(appengine.NewContext(req), (*appengine.Context)(nil)) 
}) 
Các vấn đề liên quan