2015-10-12 4 views
-2

Пытается издеваться над HTTP-ответом в тесте Go. Кода ниже, никогда не заканчивается, если я запускаю его сЗаключительный тупик

идут тест example.com/auth/...

package auth_test 
import (
    "testing" 
    "net/http/httptest" 
    "net/http" 
) 

func TestAuthorization(t *testing.T) { 
    t.Log("Should return 401 when Gateway returns 401") 
    { 
     url := oneOffUrlWithResponseCode(http.StatusUnauthorized) 
     request, _ := http.NewRequest("GET", url, nil) 
     response, _ := http.DefaultClient.Do(request) 

     if response.StatusCode != http.StatusUnauthorized { 
      t.Fatalf("Response should be 401 (Unauthorized)") 
     } 
    } 
} 

func oneOffUrlWithResponseCode(responseCode int) string { 
    var server *httptest.Server 
    server = httptest.NewServer(http.HandlerFunc(func(response http.ResponseWriter, request *http.Request) { 
     defer server.Close() 
     response.WriteHeader(responseCode) 
    })) 
    return server.URL 
} 

Однако, если я закомментировать эту строку

отложить сервер.Закрыть()

все работает нормально.

В идеале, я не хочу «утечка» * httptest.Server за пределами функции oneOffUrlWithResponseCode и, очевидно, закрывает его после первого запроса.

Почему он никогда не заканчивается? Что я делаю не так? Что правильно делать?

+0

Просто любопытно, но почему вы хотите, чтобы скрыть сервер. Кажется довольно разумным, что сервер возвращается, так как ожидается, что он будет использоваться для теста, например. сервер создается, и сервер закрывается тестом (а не его обратным вызовом). –

ответ

4

Программа не заканчивается из-за тупика (и это не имеет ничего общего с закрытием). Вы не можете вызвать Close внутри обработчика, потому что внутренне Close ждет завершения всех обработчиков.

Самый простой способ исправить это «утечка» httptest.Server вне oneOffUrlWithResponseCode:

func TestAuthorization(t *testing.T) { 
    ... 
    server := oneOffUrlWithResponseCode(http.StatusUnauthorized) 
    defer server.Close() 
    request, _ := http.NewRequest("GET", server.URL, nil) 
    ... 
} 

func oneOffUrlWithResponseCode(responseCode int) *httptest.Server { 
    return httptest.NewServer(http.HandlerFunc(func(response http.ResponseWriter, request *http.Request) { 
     response.WriteHeader(responseCode) 
    })) 
} 
+0

Другая альтернатива, на которую я хотел бы обратить внимание, заключается в том, что сервера вообще можно избежать. Обработчик может быть вызван на 'httptest.ResponseRecorder' и' http.Request'. Используя 'ResponseRecorder', вы можете проверить' .Code' и посмотреть, что он должен быть обновлен до 'http.StatusUnauthorized', так как код под тестом не делает многого. Единственное отличие состоит в том, что это единичный тест, а не интеграционный тест. –

Смежные вопросы