golang appengine ошибка тестирования API appengine: NewContext передал неизвестный http.Request

Я использую appengine и golang для разработки простых RESTful API. Код работает нормально, когда я запускаю службу с помощью goapp serve и я начал писать функции модульного тестирования для проверки конечных точек API, и тут я столкнулся с панической ошибкой appengine: NewContext passed an unknown http.Request. Я получаю эту ошибку, когда запускаю goapp test.

Похоже, по какой-то причине я не могу передать созданный мной запрос и передать его appengine.NewContext()

Ниже приведен фрагмент кода..

body := strings.NewReader("")

request, err := http.NewRequest("GET", "endpoint url", body) //inst.NewRequest("GET", goalUrl, body) //
if err != nil {
    t.Error(err)
}
t.Log(request)

c := appengine.NewContext(request) // ERROR: appengine: NewContext passed an unknown http.Request

Я создал простой воспроизводимый код. Можете ли вы помочь мне с этим? или Есть ли у кого-нибудь проект API golang на appengine и функции модульного тестирования для проверки конечных точек, я хотел бы взглянуть на их код...

Вот опубликованная мной ошибка gitlab, в которой есть все необходимые сведения о проблеме. с примерами и подробным сообщением об ошибке. Спасибо за вашу помощь.


person srini    schedule 29.10.2016    source источник


Ответы (2)


Приносим извинения за задержку с ответом. Я сам работал над решением

Вот как я решил проблему модульных тестов go appengine: полный код решения можно найти на эта ветка репозитория github.

В файле *_test.go я использовал следующее.

  • httptest.NewServer(..) для создания нового экземпляра тестового сервера. также используется для захвата базового URL-адреса службы, которая используется при подготовке объекта запроса.
  • aetest.NewContext() для создания нового контекста для целей тестирования.
  • http.NewRequest(..) для создания нового запроса
  • контекст гориллы.Set(..) для назначения ключа ("Контекст"), значения (контекст, созданный на предыдущем шаге) для запроса, созданного выше
  • httptest.NewRecorder() новый рекордер для сохранения результатов
  • http.Handler.ServeHTTP(..) передавая записанный запрос. используется для запроса API

Для каждого кода обработчика API вместо прямого создания нового контекста с помощью appengine.NewContext у меня есть код, описанный в приведенном ниже sudocode.

using the gorilla's context.GetOk(..), check 
    IF the received request object has the key "Context"
    THEN using value of that key as the context
    ELSE derive context using appengine.NewContext(r)

Я поместил повторно используемые функции в отдельную библиотеку под названием aeunittest и использовал ее в своем коде.

С этой настройкой я могу запустить тест goapp для запуска модульных тестов. см. решенный код для получения полной информации о решении.

Вот сообщение в блоге, которое помогло мне найти это решение. Большое спасибо, Марк. ТЕСТИРОВАНИЕ GO HTTP-ОБРАБОТЧИКОВ В GOOGLE APP Engine С ФУНКЦИЯМИ MUX И ВЫСШЕГО ПОРЯДКА.

person srini    schedule 09.11.2016

NewContext извлекает контекст из тестовых HTTP-запросов, т. е. зарегистрирован в нем.

Поскольку вы создаете новый запрос, неизвестный внутреннему механизму приложения package, это паника.

Этот пакет также предоставляет функцию RegisterTestRequest, но она не упоминается в основном документация так YMMV. У меня нет опыта в этом.

person nothingmuch    schedule 29.10.2016
comment
спасибо, но я вижу примечание в документе о том, что он должен использоваться только пакетом aetest. Я считаю, что это не может быть риском. Есть ли другое решение? - person srini; 31.10.2016
comment
Почему вам нужно позвонить NewContext для начала? Возможно, лучшим подходом было бы полностью разделить части логики, специфичные для appengine, и сделать логику приложения тестируемой независимо от конкретного состояния appengine? - person nothingmuch; 08.11.2016
comment
Контекст требуется для операций хранилища данных appengine, таких как put, get, поэтому он необходим в моем случае. - person srini; 10.11.2016
comment
Я имею в виду, что вы можете абстрагировать эти API в интерфейсы и предоставить фиктивный контекст и фиктивное хранилище данных для загрузки (или просто хранилище данных, если вы можете скрыть контекст), совместимые с пакетом appengine, но независимые от него. - person nothingmuch; 10.11.2016
comment
я не уверен, как это сделать. только что я опубликовал решение, которое я нашел работающим для меня. Я считаю, что это отличается от того, о чем вы говорите. Тем не менее, мне тоже интересно узнать ваше решение. - person srini; 10.11.2016