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>
raw post에 입니까?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
소스코드를 보시면 아시겠지만raw_postrequest.body.read 체크 마크를 RAW_POST_DATA request hashenv 시
레일 5 버전:
post :create, body: '{"foo": "bar", "bool": true}'
여기를 봐주세요-body bodystring raw request body로 됩니다.
rspec post request를 시뮬레이트하기 전에 한 줄만 추가하면 같은 문제를 해결할 수 있었습니다.이 작업은 "RAW_POST_DATA"를 채우는 것입니다.post:create에서 속성 var를 삭제하려고 했지만 삭제해도 액션을 찾을 수 없습니다.
제 해결책입니다.
def do_create(아트리뷰트)request.env ['RAW_POST_DATA']= 속성수신인_jsonpost : 작성, 아트리뷰트끝.
컨트롤러에서 JSON을 읽는 데 필요한 코드는 다음과 같습니다.
@syslog = Property.new(JSON.parse(request.body.read))
테스트를 실행하고 있는 스택트레이스를 보면 요구 준비에 대한 자세한 제어를 얻을 수 있습니다.액션 디스패치:통합:RequestHelpers.post = > Action Dispatch : :통합:Session.process => 랙:테스트: 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' }
통합 테스트(Rails 5.1)에서 원시 JSON 콘텐츠를 게시하는 방법을 한참 동안 검색했습니다.이 경우에도 제 솔루션이 도움이 될 수 있을 것 같습니다. i i for for 의 문서와 소스코드를 .post방법: https://api.rubyonrails.org/v5.1/classes/ActionDispatch/Integration/RequestHelpers.html#method-i-post
에게 이이 the로 했다.process자세한 내용은http://https://api.rubyonrails.org/v5.1/classes/ActionDispatch/Integration/Session.html#method-i-process 를 참조해 주세요.
에 저는 이제 알 수.process post here. 다음과 같습니다최종 솔루션은 다음과 같습니다.
post my_url, params: nil, headers: nil, env: {'RAW_POST_DATA' => my_body_content}, as: :json
2Specs를 하는 경우 은 RSpec(>= 2.12.0)입니다.ActionDispatch::Integration::Runner소스 코드를 보면 post method가 프로세스를 호출하는 것을 알 수 있습니다.이 프로세스에서는,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 4를 사용하여 컨트롤러에 게시된 raw xml의 처리를 테스트하려고 했습니다.포스트에 스트링을 제공하는 것만으로 할 수 있었습니다.
raw_xml = File.read("my_raw.xml")
post :message, raw_xml, format: :xml
제공된 파라미터가 문자열이면 본문으로 컨트롤러에 전달될 것입니다.
레일 5.1에서는 본문에 데이터가 필요한 삭제 요청을 수행할 때 다음 작업을 수행합니다.
delete your_app_url, as: :json, env: {
"RAW_POST_DATA" => {"a_key" => "a_value"}.to_json
}
메모: 이것은 연동 테스트를 실행하는 경우에만 작동합니다.
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
/disc/5/orders/10/discl에 있는 URL의 경우이것에 의해, 전달되는 URL 파라미터와 JSON 본문이 취득됩니다.물론 주문이 포함되어 있지 않은 경우에는 파라미터 해시를 생략할 수 있습니다.
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
Rails 4(적어도 4.2.11.3에서는)에서는 json(기능 테스트)을 사용하는 컨트롤러를 쉽게 테스트할 수 없습니다.실행 중인 서버에서 json을 해석하는 경우 미들웨어가 담당합니다.컨트롤러 테스트는 랙에 의존하며, 랙은 오늘날까지 json을 해석할 수 없습니다(필요한 것은 아닙니다).
다음 작업을 수행할 수 있습니다.
post :create, body_params.to_json
또는 다음과 같이 입력합니다.
post :update, body_parmas.to_json, url_params
★★★★★★★★★★★★★★★★★.body_params 할 수params돼요JSON.parse(request.body.read)그래서 생각나는 것은 다음과 같습니다.
post :update, url_params.merge(body_params)
에서는 모든 것을 즉, 스, 테((테(((((((((((((((((((((((((()로 시킵니다.application/x-www-form-urlencoded 시 ActionDispatch::ParamsParser같은 취지로.단, 숫자가 문자열(및 그 이상일 수 있음)이 되는 경우는 다음과 같습니다.
# test/controllers/post_controller_test.rb
post :update, {id: 1, n: 2}
# app/controller/posts_controller.rb
def update
p params # tests:
# {"id"=>"1", "n" => "2", "controller"=>"posts", "action"=>"update"}
# production
# {"id"=>"1", "n" => 2, "controller"=>"posts", "action"=>"update"}
end
컨트롤러에서 직접 json을 구문 분석할 의향이 있는 경우 다음을 수행할 수 있습니다.
# test/controllers/post_controller_test.rb
post_json :update, {n: 2}.to_json, {id: 1}
# app/controller/posts_controller.rb
def update
p JSON.parse(request.body.read) # {"id"=>"1", "n" => 2, "controller"=>"posts", "action"=>"update"}
end
post :index, {:foo=> 'bar', :bool => 'true'}
언급URL : https://stackoverflow.com/questions/2103977/how-to-send-raw-post-data-in-a-rails-functional-test
'programing' 카테고리의 다른 글
| Python의 json 모듈, int 사전 키를 문자열로 변환 (0) | 2023.03.05 |
|---|---|
| Kotlin + Jackson을 사용하여 JSON을 목록으로 역직렬화하려면 어떻게 해야 합니까? (0) | 2023.03.05 |
| Ajax를 ASP.net MVC 컨트롤러에 게시 - 개체 속성이 null입니다. (0) | 2023.03.05 |
| 사용자 역할에 따른 AngularJS, ui.router, 로드 템플릿 및 컨트롤러 (0) | 2023.03.05 |
| 스프링 부트에서 다양한 유형의 ResponseEntity를 반환하는 가장 좋은 방법(스프링에서의 REST 오류 처리) (0) | 2023.03.05 |