2013-07-15 2 views
4

Я использую следующий код для выполнения запроса на сервере внутри задачи граблей:Принуждение app.get Rails, чтобы повторить запрос

app = ActionDispatch::Integration::Session.new(Rails.application) 
app.host!('localhost:3000') 
app.get(path) 

Это хорошо работает.

Однако, если я снова вызываю app.get(path) с тем же путем, запрос не повторяется и возвращается предыдущий результат.

Есть ли способ заставить приложение app повторить вызов?

+1

Откуда вы знаете, что второй 'app.get (path)' не повторяет запрос? Я просто просмотрел код для «ActionDispatch :: Integration :: Session», и никаких признаков кэширования там нет. – henrikhodne

+0

@henrikhodne любой 'puts' присутствует в методе контроллера, который обслуживает маршрут, будет выводиться только по первому запросу. –

+0

@henrikhodne, вы правы. Это не «ActionDispatch :: Integration :: Session», выполняющее какое-либо кэширование, но стандартный кеширующий рельсы делает это, как со стандартным HTTP-запросом. Я уточнил в своем ответе. –

ответ

1

Я разработал то, что происходит.

В основном наблюдение «запрос не повторяется» является собственным кэшированием Rails в действии. Что имеет смысл, app.get рассматривается как любой другой запрос, если кеширование включено, кеш возвращается, а если нет, он будет повторяться (как утверждал @henrikhodne). Это объясняет, почему puts в кэшированном контроллере не будет выводиться во второй раз.

Чтобы проверить, добавьте puts в 2 способах управления, но только установите expires_in во втором. Первый повторит выход, второй - нет.

Способ принудительного повторения запроса состоит в том, чтобы перекрыть кеш, изменив URL-адрес, например. app.get("/") будет app.get("/?r=123456") как если бы, используя HTTP. Все это кажется очевидным в ретроспективе, в основном app.get обрабатывается точно как запрос клиента, и применяются все те же правила.

1

Попытка сбросить сессию:

app.reset! 

Вот как он работает при перезапуске,

def reset! 
    @https = false 
    @controller = @request = @response = nil 
    @_mock_session = nil 
    @request_count = 0 
    @url_options = nil 

    self.host  = DEFAULT_HOST 
    self.remote_addr = "127.0.0.1" 
    self.accept  = "text/xml,application/xml,application/xhtml+xml," + 
         "text/html;q=0.9,text/plain;q=0.8,image/png," + 
         "*/*;q=0.5" 

    unless defined? @named_routes_configured 
     # the helpers are made protected by default--we make them public for 
     # easier access during testing and troubleshooting. 
     @named_routes_configured = true 
    end 
    end 

В противном случае он просто будет повторно использовать последний ответ:

# this is a private method in Session, it will called every time you call `get/post, etc` 
def process 
    ...... 
    @request_count += 1 
    @request = ActionDispatch::Request.new(session.last_request.env) 
    response = _mock_session.last_response 
    @response = ActionDispatch::TestResponse.new(response.status, response.headers, response.body) 
    @html_document = nil 
    .... 
end 

Удачи!

+1

На самом деле он не повторяет последний ответ. Если вы посмотрите немного дальше в коде, он отправит запрос на '_mock_session', переопределяя атрибут last_response. '#reset!' все еще может работать. – henrikhodne

+0

'app.reset!' Не повлиял на мое тестирование. Моя проблема заключалась в активации собственной системы кэширования (как для обычного HTTP-запроса), см. Мой ответ. Я ценю вашу помощь, исследуя это, хотя! –

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