Rails 기능 테스트에서 원시 포스트 데이터를 보내는 방법은 무엇입니까?
테스트를 위해 내 컨트롤러 중 하나에 원시 게시물 데이터 (예 : 매개 변수화되지 않은 JSON)를 보내려고합니다.
class LegacyOrderUpdateControllerTest < ActionController::TestCase
test "sending json" do
post :index, '{"foo":"bar", "bool":true}'
end
end
그러나 이것은 나에게 NoMethodError: undefined method `symbolize_keys' for #<String:0x00000102cb6080>
오류를 준다 .
원시 게시물 데이터를 보내는 올바른 방법은 무엇입니까 ActionController::TestCase
?
다음은 컨트롤러 코드입니다.
def index
post_data = request.body.read
req = JSON.parse(post_data)
end
나는 오늘 같은 문제를 겪었고 해결책을 찾았습니다.
당신에하는 것은 test_helper.rb
다음과 같은 방법의 내부를 정의한다 ActiveSupport::TestCase
:
def raw_post(action, params, body)
@request.env['RAW_POST_DATA'] = body
response = post(action, params)
@request.env.delete('RAW_POST_DATA')
response
end
기능 테스트에서 post
메서드 처럼 사용 하되 원시 게시물 본문을 세 번째 인수로 전달하십시오.
class LegacyOrderUpdateControllerTest < ActionController::TestCase
test "sending json" do
raw_post :index, {}, {:foo => "bar", :bool => true}.to_json
end
end
나는 이것을 사용하여 원시 포스트 본문을 읽을 때 Rails 2.3.4에서 테스트했습니다.
request.raw_post
대신에
request.body.read
소스 코드 를 살펴보면 env 해시 에서 이를 확인하여 raw_post
래핑 request.body.read
하는 것을 볼 수 있습니다 .RAW_POST_DATA
request
실제로 rspec 게시 요청을 시뮬레이션하기 전에 한 줄만 추가하면 동일한 문제를 해결했습니다. 당신이하는 일은 "RAW_POST_DATA"를 채우는 것입니다. 나는 post : create에서 var 속성을 제거하려고 시도했지만 그렇게하면 작업을 찾지 못했습니다.
여기 내 해결책.
def do_create (속성) request.env [ 'RAW_POST_DATA'] = attributes.to_json 포스트 : 생성, 속성 종료
컨트롤러에서 JSON을 읽는 데 필요한 코드는 다음과 유사합니다.
@property = Property.new (JSON.parse (request.body.read))
테스트를 실행하는 스택 추적을 보면 요청 준비시 더 많은 제어를 얻을 수 있습니다. ActionDispatch :: Integration :: RequestHelpers.post => ActionDispatch :: Integration :: Session.process => Rack :: Test :: Session.env_for
json 문자열을 : params로 전달하고 콘텐츠 유형 "application / json"을 지정할 수 있습니다. 다른 경우에는 콘텐츠 유형이 "application / x-www-form-urlencoded"로 설정되고 json이 제대로 구문 분석됩니다.
따라서 "CONTENT_TYPE"을 지정하기 만하면됩니다.
post :index, '{"foo":"bar", "bool":true}', "CONTENT_TYPE" => 'application/json'
Rails5 + 통합 테스트를 사용하는 경우 (문서화되지 않은) 방법은 params 인수에 문자열을 전달하는 것입니다.
post '/path', params: raw_body, headers: { 'Content-Type' => 'application/json' }
RSpec (> = 2.12.0)을 사용하고 요청 사양을 작성하는 경우 포함 된 모듈은 ActionDispatch::Integration::Runner
. 소스 코드를 살펴보면 post 메소드가 매개 변수 를 받아들이는 프로세스 를 호출 한다는 것을 알 수 있습니다 rack_env
.
이 모든 것은 사양에서 다음을 수행 할 수 있음을 의미합니다.
#spec/requests/articles_spec.rb
post '/articles', {}, {'RAW_POST_DATA' => 'something'}
그리고 컨트롤러에서 :
#app/controllers/articles_controller.rb
def create
puts request.body.read
end
Rails 5 용 버전 :
post :create, body: '{"foo": "bar", "bool": true}'
여기를 참조 하십시오 - body
문자열 매개 변수는 원시 요청 본문으로 처리됩니다.
Rails 4를 사용하여 컨트롤러에 게시되는 원시 xml의 처리를 테스트하기 위해이 작업을 수행하려고했습니다. 게시물에 문자열을 제공하기 만하면됩니다.
raw_xml = File.read("my_raw.xml")
post :message, raw_xml, format: :xml
제공된 매개 변수가 문자열이면 컨트롤러에 본문으로 전달됩니다.
이 post
메서드는 이름-값 쌍의 해시를 예상하므로 다음과 같은 작업을 수행해야합니다.
post :index, :data => '{"foo":"bar", "bool":true}'
그런 다음 컨트롤러에서 다음과 같이 구문 분석 할 데이터를 가져옵니다.
post_data = params[:data]
Rails 4.1.5부터는 이것이 저에게 효과적이었습니다.
class LegacyOrderUpdateControllerTest < ActionController::TestCase
def setup
@request.headers["Content-Type"] = 'application/json'
end
test "sending json" do
post :index, '{"foo":"bar", "bool":true}'.to_json, { account_id: 5, order_id: 10 }
end
end
/ accounts / 5 / orders / 10 / items의 URL에 대해 이것은 전달 된 URL 매개 변수와 JSON 본문을 가져옵니다. 물론 주문이 포함되지 않은 경우 params 해시를 생략 할 수 있습니다.
class LegacyOrderUpdateControllerTest < ActionController::TestCase
def setup
@request.headers["Content-Type"] = 'application/json'
end
test "sending json" do
post :index, '{"foo":"bar", "bool":true}'.to_json
end
end
레일즈 5.1에서는 본문에 데이터가 필요한 삭제 요청을 수행 할 때 다음 작업이 수행됩니다.
delete your_app_url, as: :json, env: {
"RAW_POST_DATA" => {"a_key" => "a_value"}.to_json
}
참고 : 이것은 통합 테스트를 수행 할 때만 작동합니다.
통합 테스트 (Rails 5.1)에서 원시 JSON 콘텐츠를 게시하는 방법을 오랫동안 찾고있었습니다. 이 경우 내 솔루션이 도움이 될 수 있다고 생각합니다. post
메서드에 대한 문서와 소스 코드를 찾았습니다 . https://api.rubyonrails.org/v5.1/classes/ActionDispatch/Integration/RequestHelpers.html#method-i-post
이것은 저를 지시 process
자세한 내용은 방법 : https://api.rubyonrails.org/v5.1/classes/ActionDispatch/Integration/Session.html#method-i-process
Thanks to this, I finally found out what parameters are accepted by the process
and thus post
method. Here's what my final solution looked like:
post my_url, params: nil, headers: nil, env: {'RAW_POST_DATA' => my_body_content}, as: :json
post :index, {:foo=> 'bar', :bool => 'true'}
ReferenceURL : https://stackoverflow.com/questions/2103977/how-to-send-raw-post-data-in-a-rails-functional-test
'IT이야기' 카테고리의 다른 글
for 루프 다중 처리 (0) | 2021.04.22 |
---|---|
jQuery datepicker- 2 개의 입력 / 텍스트 상자 및 제한 범위 (0) | 2021.04.21 |
Perl 프로그래머를위한 Python (0) | 2021.04.21 |
오디오 샘플의 키를 결정하는 알고리즘 (0) | 2021.04.21 |
Firefox에서 원격으로 Google Maps V3를 사용할 때 "google이 정의되지 않았습니다." (0) | 2021.04.21 |