Как использовать символы кода статуса HTTP в RSpec?

я используюСимволы кода состояния HTTP в коде в контроллере, таком как:

render json: {
    auth_token: user.authentication_token, 
    user: user
  }, 
  status: :created

или же

render json: {
    errors: ["Missing parameter."]
  }, 
  success: false, 
  status: :unprocessable_entity

В коде моей спецификации запроса я также хотел бы использовать символы:

post user_session_path, email: @user.email, password: @user.password
expect(last_response.status).to eq(201)

...

expect(last_response.status).to eq(422)

Однако каждый тест, где я использую символы вместо целых чисел, терпит неудачу:

Failure/Error: expect(last_response.status).to eq(:created)

  expected: :created
       got: 201

  (compared using ==)

Вот последний списокСимволы кода состояния HTTP в стойке.

Ответы на вопрос(4)

response Объект отвечает на несколько типов символов в виде сообщений. Так что вы можете просто сделать:

expect(response).to be_error
expect(response).to be_missing
expect(response).to be_redirect

Для других типов, таких как:created, вы можете создать простой пользовательский сопоставитель для этого, который оборачивает:assert_response

RSpec::Matchers.define :have_status do |type, message = nil|
  match do |_response|
    assert_response type, message
  end
end

expect(response).to have_status(:created)
expect(response).to have_status(404)

Это должно работать нормально для спецификаций контроллера, которые имеют правильную настройку состояния. Будетне работа для спецификации функций. У меня нетпробовал со спецификациями запроса, поэтому ваш пробег может варьироваться.

Причина, по которой это работает, заключается в том, что он использует тот факт, что спецификации контроллера RSpec имеют аналогичную настройку состояния за кулисами. Так когдаassert_response доступ@response это доступно.

Этот сопоставитель, вероятно, можно улучшить, просто скопировав код, используемыйassert_response в соответствие:

RSpec::Matchers.define :have_status do |type, message = nil|
  match do |response|
    if Symbol === type
      if [:success, :missing, :redirect, :error].include?(type)
        response.send("#{type}?")
      else
        code = Rack::Utils::SYMBOL_TO_STATUS_CODE[type]
        response.response_code == code
      end
    else
      response.response_code == type
    end
  end

  failure_message do |response|
    message or
      "Expected response to be a <#{type}>, but was <#{response.response_code}>"
  end
end
ОБНОВЛЕНИЕ: 2014-07-02

Это теперь доступно из коробки с RSpec Rails 3:https://www.relishapp.com/rspec/rspec-rails/v/3-0/docs/matchers/have-http-status-matcher

Решение Вопроса

успех?

перенаправление?

unprocessable?

Полный список сделать:response.methods.grep(/\?/)

С другой стороны, предикаты Rspec преобразуют каждыйfoo? метод кbe_foo согласовани.

Не уверен, что вы можете получить 201 таким образом, но создать собственный сопоставитель довольно просто.

Примечание только для Rails testполагаться на несколько статусов.

 JJD16 авг. 2013 г., 17:01
Я админ, я не так хорошо прочитал ваши комментарии, но на этот раз не получится »неопределенный метод `success? ' для # <Стеллаж :: MockResponse: 0x000000058c1180>»
 JJD16 авг. 2013 г., 17:07
Тест запроса, который я выполняю, находится в.spec/api/sessions_controller_spec.rb
 JJD16 авг. 2013 г., 16:47
Так же:expect(last_response.status).to be_success не с "неопределенный метод 'успех? на 201: Fixnum ", Я понял этоcreated? не является частью списка и экспериментировал с пользовательским соответствием ... пока без успеха.
 JJD16 авг. 2013 г., 17:14
Я мог бы неправильно понять, ноrspec-rails штаты спецификации запроса принадлежат либоspec/requestsspec/api или же .spec/integration
 apneadiving16 авг. 2013 г., 17:43
в спецификации функции вы не должны беспокоиться оresponse, вы должны работать над.pageresponse для контроллеров спец.
 apneadiving16 авг. 2013 г., 17:03
почему у тебя это должно бытьActionController::TestResponse, где живут твои спецификации?
 JJD16 авг. 2013 г., 17:42
Благодарю. Но когда я перенесу тест вspec/features это не сundefined local variable or method 'app' for #
 apneadiving16 авг. 2013 г., 17:44
Я не знаю, что и как вы сделали, но когда вы не следуете стандартным путям,нормально, вы сталкиваетесь со многими проблемами /
 apneadiving16 авг. 2013 г., 16:33
это не помогает?
 JJD16 авг. 2013 г., 23:45
Без обид, пожалуйста. Я последний, кто забывает голосовать за людейс помощью. Хотя обычно я жду, пока я полностью не решу проблему, прежде чем я проголосую или предоставлю флаг ответа.
 JJD16 авг. 2013 г., 16:45
Я старалсяexpect(last_response.status).to be_created который терпит неудачу с "неопределенный метод `создан? ' для 201: Fixnum ".
 apneadiving16 авг. 2013 г., 16:45
expect(last_response).to be_success
 apneadiving16 авг. 2013 г., 16:46
уведомлениеcreated? не является частью списка методов
 JJD16 авг. 2013 г., 18:48
Я стараюсь следовать вашим советам иучебники, как это но я все еще могуЗапусти. Чтобы избежать дальнейшего отклонения от моего первоначального вопросавот новый пост.
 apneadiving16 авг. 2013 г., 17:24
по вашей ссылке:Note that Capybara's DSL as shown is, by default, only available in specs in the spec/features directory
 apneadiving16 авг. 2013 г., 17:09
запросить спец? спецификации запроса должны жить вspec/features, спецификация контроллера должна жить вspec/controllersиначе будут добавлены неправильные модули (если вы не включите их вручную)
 apneadiving16 авг. 2013 г., 16:56
перечитайте то, что я написал:expect(last_response) неexpect(last_response.status)
 apneadiving16 авг. 2013 г., 18:03
Это должны быть спецификации контроллера, а выя мог бы использовать то, что я положил в своем ответе
 JJD16 авг. 2013 г., 17:45
Я думаю, что я на неправильном пути. Можете ли вы указать правильный путь, чтобы проверить ответ моих конечных точек API?
 apneadiving16 авг. 2013 г., 20:43
Вы потратили много времени на ваш вопрос без партнера, не так ли?не ожидайте, что я потрачу больше в другом месте. извиняюсь.

СRSpec рельсы (по состоянию наRSpec 3) этоможно использовать

expect(response).to have_http_status(:created)

Обновление 2018-06-11:

Начиная с Rails 6, некоторые из сопоставителей будут заменены (например,success отsuccessful).

 Tinynumbers15 мая 2015 г., 23:33
Только в версии 3 RSpec или позже.have_http_status не входит в RSpec 2.

expect(response.response_code).to eq(Rack::Utils::SYMBOL_TO_STATUS_CODE[:not_found])

Ваш ответ на вопрос