RSpec을 사용하여 JSON 응답을 확인하는 방법은 무엇입니까?
컨트롤러에 다음 코드가 있습니다.
format.json { render :json => {
:flashcard => @flashcard,
:lesson => @lesson,
:success => true
}
내 RSpec 컨트롤러 테스트에서 특정 시나리오가 성공 json 응답을 수신하는지 확인하여 다음 줄을 가지고 싶습니다.
controller.should_receive(:render).with(hash_including(:success => true))
테스트를 실행할 때 다음 오류가 발생합니다.
Failure/Error: controller.should_receive(:render).with(hash_including(:success => false))
(#<AnnoController:0x00000002de0560>).render(hash_including(:success=>false))
expected: 1 time
received: 0 times
응답을 잘못 확인하고 있습니까?
응답 오브젝트를 검사하고 예상 값을 포함하는지 검증 할 수 있습니다.
@expected = {
:flashcard => @flashcard,
:lesson => @lesson,
:success => true
}.to_json
get :action # replace with action name / params as necessary
response.body.should == @expected
편집하다
이것을 변경하면 post
조금 까다로워집니다. 처리 방법은 다음과 같습니다.
it "responds with JSON" do
my_model = stub_model(MyModel,:save=>true)
MyModel.stub(:new).with({'these' => 'params'}) { my_model }
post :create, :my_model => {'these' => 'params'}, :format => :json
response.body.should == my_model.to_json
end
주 mock_model
에 응답하지 않습니다 to_json
그래서 중 하나, stub_model
또는 실제 모델 인스턴스가 필요합니다.
다음과 같이 응답 본문을 구문 분석 할 수 있습니다.
parsed_body = JSON.parse(response.body)
그런 다음 구문 분석 된 컨텐츠에 대해 어설 션을 작성할 수 있습니다.
parsed_body["foo"].should == "bar"
의 오프 구축 케빈 트로 브리지의 대답
response.header['Content-Type'].should include 'application/json'
json_spec gem 도 있습니다.
https://github.com/collectiveidea/json_spec
간단하고 쉬운 방법입니다.
# set some variable on success like :success => true in your controller
controller.rb
render :json => {:success => true, :data => data} # on success
spec_controller.rb
parse_json = JSON(response.body)
parse_json["success"].should == true
내부에 도우미 함수를 정의 할 수도 있습니다 spec/support/
module ApiHelpers
def json_body
JSON.parse(response.body)
end
end
RSpec.configure do |config|
config.include ApiHelpers, type: :request
end
json_body
JSON 응답에 액세스해야 할 때마다 사용 하십시오.
예를 들어 요청 사양 내에서 직접 사용할 수 있습니다.
context 'when the request contains an authentication header' do
it 'should return the user info' do
user = create(:user)
get URL, headers: authenticated_header(user)
expect(response).to have_http_status(:ok)
expect(response.content_type).to eq('application/vnd.api+json')
expect(json_body["data"]["attributes"]["email"]).to eq(user.email)
expect(json_body["data"]["attributes"]["name"]).to eq(user.name)
end
end
JSON 응답 만 테스트하는 다른 방법 (내의 내용에 예상 값이 포함되어 있지 않음)은 ActiveSupport를 사용하여 응답을 구문 분석하는 것입니다.
ActiveSupport::JSON.decode(response.body).should_not be_nil
응답이 구문 분석 가능한 JSON이 아닌 경우 예외가 발생하고 테스트가 실패합니다.
당신은에 볼 수 있었다 'Content-Type'
올바른지 확인 헤더?
response.header['Content-Type'].should include 'text/javascript'
When using Rails 5 (currently still in beta), there's a new method, parsed_body
on the test response, which will return the response parsed as what the last request was encoded at.
The commit on GitHub: https://github.com/rails/rails/commit/eee3534b
If you want to take advantage of the hash diff Rspec provides, it is better to parse the body and compare against a hash. Simplest way I've found:
it 'asserts json body' do
expected_body = {
my: 'json',
hash: 'ok'
}.stringify_keys
expect(JSON.parse(response.body)).to eql(expected_body)
end
I found a customer matcher here: https://raw.github.com/gist/917903/92d7101f643e07896659f84609c117c4c279dfad/have_content_type.rb
Put it in spec/support/matchers/have_content_type.rb and make sure to load stuff from support with something like this in you spec/spec_helper.rb
Dir[Rails.root.join('spec/support/**/*.rb')].each {|f| require f}
Here is the code itself, just in case it disappeared from the given link.
RSpec::Matchers.define :have_content_type do |content_type|
CONTENT_HEADER_MATCHER = /^(.*?)(?:; charset=(.*))?$/
chain :with_charset do |charset|
@charset = charset
end
match do |response|
_, content, charset = *content_type_header.match(CONTENT_HEADER_MATCHER).to_a
if @charset
@charset == charset && content == content_type
else
content == content_type
end
end
failure_message_for_should do |response|
if @charset
"Content type #{content_type_header.inspect} should match #{content_type.inspect} with charset #{@charset}"
else
"Content type #{content_type_header.inspect} should match #{content_type.inspect}"
end
end
failure_message_for_should_not do |model|
if @charset
"Content type #{content_type_header.inspect} should not match #{content_type.inspect} with charset #{@charset}"
else
"Content type #{content_type_header.inspect} should not match #{content_type.inspect}"
end
end
def content_type_header
response.headers['Content-Type']
end
end
참고URL : https://stackoverflow.com/questions/5159882/how-to-check-for-a-json-response-using-rspec
'IT story' 카테고리의 다른 글
git 저장소에서 병합 한 후 .orig 파일을 삭제하는 방법은 무엇입니까? (0) | 2020.06.19 |
---|---|
SQL Server Reporting Services 보고서에 대체 행 색 추가 (0) | 2020.06.19 |
VB.net의 InputDialog의 C # 버전은 무엇입니까? (0) | 2020.06.19 |
Y 축의 최대 값과 최소값을 설정하는 방법 (0) | 2020.06.19 |
안드로이드 키보드 해제 (0) | 2020.06.19 |