Editor PHP Baicao memperkenalkan anda kepada alat ujian unit yang dipanggil "httptest", yang boleh membantu pembangun menguji apabila mencuba semula permintaan http. Alat ini bukan sahaja boleh mensimulasikan pelbagai permintaan http, tetapi juga secara automatik mencuba semula permintaan untuk memastikan kestabilan dan kebolehpercayaan kod. Menggunakan alat httptest, pembangun boleh menguji permintaan http dengan mudah dan boleh mencuba semula permintaan dengan mudah sebagai tindak balas kepada ketidakstabilan rangkaian atau situasi luar biasa lain. Penggunaan alat ini boleh meningkatkan kecekapan pembangunan dan mengurangkan kemungkinan ralat Ia adalah alat yang patut dicuba untuk setiap pembangun PHP.
Saya cuba menulis ujian unit untuk komponen yang dipanggil HttpRequest
yang membungkus permintaan HTTP dan mengendalikan penolakan respons. Baru-baru ini, saya menambah ciri pada komponen ini yang membolehkannya mencuba semula permintaan HTTP jika ia menghadapi ralat "sambungan ditolak" pada percubaan pertama.
Untuk menggunakan komponen HttpRequest, saya memanggilnya sekali: user, err := HttpRequest[User](config)
。 config 参数包含执行请求的所有必要信息,例如 URL、方法、超时、重试次数和请求正文。它还将响应正文解组为指定类型的实例(在本例中为 User
)
Masalah timbul apabila saya cuba menguji senario di mana permintaan awal gagal dengan ralat "Sambungan ditolak" tetapi percubaan kedua berjaya. Percubaan semula berlaku di dalam komponen, jadi saya hanya membuat satu panggilan ke komponen.
Saya mendapati sukar untuk membuat ujian unit untuk senario ini kerana agar permintaan gagal dengan "Sambungan ditolak" tidak perlu ada pendengar pada port yang dipanggil. Masalahnya ialah, apabila menggunakan contoh httptest
时,它总是在创建实例时侦听端口,即使使用 httptest.NewUnstartedServer
也是如此。因此,在创建 httptest
, saya tidak pernah mendapat ralat "Sambungan ditolak" dalam kod pelanggan saya.
Walau bagaimanapun, panggilan HttpRequest dibuat sebelum kejadian httptest
实例之前,我不知道它将侦听哪个端口。 httptest
总是选择一个随机端口,并且无法以编程方式指定一个端口。这意味着我无法在创建 httptest
dibuat.
Adakah sesiapa mempunyai sebarang idea tentang cara menguji senario ini dengan berkesan?
newunstartedserver
Sangat mudah:
func newunstartedserver(handler http.handler) *server { return &server{ listener: newlocallistener(), config: &http.server{handler: handler}, } }
Jika memilih port sendiri sesuai untuk anda, anda boleh melakukan ini:
func mynewunstartedserver(port int, handler http.handler) *httptest.server { addr := fmt.sprintf("127.0.0.1:%d", port) l, err := net.listen("tcp", addr) if err != nil { addr = fmt.sprintf("[::1]::%d", port) if l, err = net.listen("tcp6", addr); err != nil { panic(fmt.sprintf("httptest: failed to listen on a port: %v", err)) } } return &httptest.server{ listener: l, config: &http.server{handler: handler}, } }
Kod untuk mencipta pendengar diubah suai daripada httptest.newlocallistener
.
Pilihan lain ialah melaksanakan http.roundtripper
接口并使用此 roundtripper 创建一个 http.client
. Berikut ialah contoh http/client_test.go disalin daripada net/:
type recordingTransport struct { req *Request } func (t *recordingTransport) RoundTrip(req *Request) (resp *Response, err error) { t.req = req return nil, errors.New("dummy impl") } func TestGetRequestFormat(t *testing.T) { setParallel(t) defer afterTest(t) tr := &recordingTransport{} client := &Client{Transport: tr} url := "http://dummy.faketld/" client.Get(url) // Note: doesn't hit network if tr.req.Method != "GET" { t.Errorf("expected method %q; got %q", "GET", tr.req.Method) } if tr.req.URL.String() != url { t.Errorf("expected URL %q; got %q", url, tr.req.URL.String()) } if tr.req.Header == nil { t.Errorf("expected non-nil request Header") } }
Atas ialah kandungan terperinci Permintaan http ujian unit cuba semula menggunakan httptest. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!