Как использовать символы кода состояния 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 в стойке.
Ответы
Ответ 1
С одной стороны, ответ строится с помощью таких методов, как:
С другой стороны, предикаты Rspec преобразует каждый метод foo?
в be_foo
.
Не уверен, что у вас может быть 201 такой способ, к сожалению, но создание пользовательского совпадения довольно просто.
Только те тесты Note Rails полагаются на несколько статусов.
Ответ 2
это работает для меня:
expect(response.response_code).to eq(Rack::Utils::SYMBOL_TO_STATUS_CODE[:not_found])
Ответ 3
Объект response
отвечает на несколько типов символов в виде сообщений. Поэтому вы можете просто:
expect(response).to be_success
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
Ответ 4
С rspec-rails (по rspec v3.0) можно использовать
expect(response).to have_http_status(:created)