Let's Go تمرین‌های راهنما › تست handler snippetCreate
قبلی · فهرست · بعدی
فصل ۱۶.۳.

تست handler snippetCreate

هدف شما در این تمرین ایجاد یک تست end-to-end برای route GET /snippet/create است. به طور خاص، می‌خواهید تست کنید که:

مرحله 1

یک تست جدید TestSnippetCreate در فایل cmd/web/handlers_test.go ایجاد کنید. در این تست، از الگو و helperهای فصل تست end-to-end برای مقداردهی اولیه یک سرور تست با استفاده از routeهای برنامه و dependencyهای mock شده استفاده کنید.

نمایش کد پیشنهادی

مرحله 2

یک sub-test با نام "Unauthenticated" ایجاد کنید. در این sub-test، یک درخواست GET /snippet/create در برابر سرور تست به عنوان یک کاربر احراز هویت نشده انجام دهید. تأیید کنید که پاسخ کد وضعیت 303 و یک header Location: /user/login دارد. دوباره، از helperهایی که در فصل تست end-to-end ساختیم استفاده مجدد کنید.

نمایش کد پیشنهادی

مرحله 3

یک sub-test دیگر با نام "Authenticated” ایجاد کنید. در این sub-test، workflow ورود به عنوان یک کاربر برای احراز هویت را تقلید کنید. به طور خاص، باید یک درخواست GET /user/login انجام دهید، CSRF token را از بدنه پاسخ استخراج کنید، سپس یک درخواست POST /user/login با استفاده از اعتبارنامه‌های موجود در model کاربر mock (ایمیل "alice@example.com"، رمز عبور "pa$$word") انجام دهید.

سپس پس از احراز هویت، یک درخواست GET /snippet/create انجام دهید و تأیید کنید که کد وضعیت 200 و یک بدنه HTML شامل متن <form action='/snippet/create' method='POST'> دریافت می‌کنید.

نمایش کد پیشنهادی

کد پیشنهادی

کد پیشنهادی برای مرحله 1

File: cmd/web/handlers_test.go
...

func TestSnippetCreate(t *testing.T) {
    app := newTestApplication(t)
    ts := newTestServer(t, app.routes())
    defer ts.Close()
}

کد پیشنهادی برای مرحله 2

File: cmd/web/handlers_test.go
...

func TestSnippetCreate(t *testing.T) {
    app := newTestApplication(t)
    ts := newTestServer(t, app.routes())
    defer ts.Close()

    t.Run("Unauthenticated", func(t *testing.T) {
        code, headers, _ := ts.get(t, "/snippet/create")
        
        assert.Equal(t, code,  http.StatusSeeOther)
        assert.Equal(t, headers.Get("Location"), "/user/login")
    })
}
$  go test -v -run=TestSnippetCreate ./cmd/web/
=== RUN   TestSnippetCreate
=== RUN   TestSnippetCreate/Unauthenticated
--- PASS: TestSnippetCreate (0.01s)
    --- PASS: TestSnippetCreate/Unauthenticated (0.00s)
PASS
ok      snippetbox.alexedwards.net/cmd/web      0.010s

کد پیشنهادی برای مرحله 3

File: cmd/web/handlers_test.go
...

func TestSnippetCreate(t *testing.T) {
    app := newTestApplication(t)
    ts := newTestServer(t, app.routes())
    defer ts.Close()

    t.Run("Unauthenticated", func(t *testing.T) {
        code, headers, _ := ts.get(t, "/snippet/create")
        
        assert.Equal(t, code,  http.StatusSeeOther)
        assert.Equal(t, headers.Get("Location"), "/user/login")
    })
    
    t.Run("Authenticated", func(t *testing.T) {
        // Make a GET /user/login request and extract the CSRF token from the
        // response.
        _, _, body := ts.get(t, "/user/login")
        csrfToken := extractCSRFToken(t, body)

        // Make a POST /user/login request using the extracted CSRF token and
        // credentials from our the mock user model.
        form := url.Values{}
        form.Add("email", "alice@example.com")
        form.Add("password", "pa$$word")
        form.Add("csrf_token", csrfToken)
        ts.postForm(t, "/user/login", form)

        // Then check that the authenticated user is shown the create snippet
        // form.
        code, _, body := ts.get(t, "/snippet/create")
        
        assert.Equal(t, code,  http.StatusOK)
        assert.StringContains(t, body, "<form action='/snippet/create' method='POST'>")
    })
}
$ go test -v -run=TestSnippetCreate ./cmd/web/
=== RUN   TestSnippetCreate
=== RUN   TestSnippetCreate/Unauthenticated
=== RUN   TestSnippetCreate/Authenticated
--- PASS: TestSnippetCreate (0.01s)
    --- PASS: TestSnippetCreate/Unauthenticated (0.00s)
    --- PASS: TestSnippetCreate/Authenticated (0.00s)
PASS
ok      snippetbox.alexedwards.net/cmd/web      0.012s