Ruby-on-rails 如何使用 RSpec 检查 JSON 响应?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5159882/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to check for a JSON response using RSpec?
提问by Fizz
I have the following code in my controller:
我的控制器中有以下代码:
format.json { render :json => {
:flashcard => @flashcard,
:lesson => @lesson,
:success => true
}
In my RSpec controller test I want to verify that a certain scenario does receive a success json response so I had the following line:
在我的 RSpec 控制器测试中,我想验证某个场景确实收到了成功的 json 响应,所以我有以下行:
controller.should_receive(:render).with(hash_including(:success => true))
Although when I run my tests I get the following error:
虽然当我运行我的测试时,我收到以下错误:
Failure/Error: controller.should_receive(:render).with(hash_including(:success => false))
(#<AnnoController:0x00000002de0560>).render(hash_including(:success=>false))
expected: 1 time
received: 0 times
Am I checking the response incorrectly?
我是否错误地检查了响应?
回答by zetetic
You can examine the response object and verify that it contains the expected value:
您可以检查响应对象并验证它是否包含预期值:
@expected = {
:flashcard => @flashcard,
:lesson => @lesson,
:success => true
}.to_json
get :action # replace with action name / params as necessary
response.body.should == @expected
EDIT
编辑
Changing this to a postmakes it a bit trickier. Here's a way to handle it:
将其更改为 apost会使它变得有点棘手。这是一种处理方法:
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
Note that mock_modelwill not respond to to_json, so either stub_modelor a real model instance is needed.
请注意,mock_model不会响应to_json,因此需要stub_model一个真实的模型实例。
回答by brentmc79
You could parse the response body like this:
您可以像这样解析响应正文:
parsed_body = JSON.parse(response.body)
Then you can make your assertions against that parsed content.
然后,您可以对该解析的内容进行断言。
parsed_body["foo"].should == "bar"
回答by lightyrs
Building off of Kevin Trowbridge's answer
response.header['Content-Type'].should include 'application/json'
回答by acw
There's also the json_specgem, which is worth a look
还有json_specgem,值得一看
回答by Chitrank Samaiya
Simple and easy to way to do this.
简单易行的方法来做到这一点。
# 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
回答by Lorem Ipsum Dolor
You can also define a helper function inside spec/support/
你也可以在里面定义一个辅助函数 spec/support/
module ApiHelpers
def json_body
JSON.parse(response.body)
end
end
RSpec.configure do |config|
config.include ApiHelpers, type: :request
end
and use json_bodywhenever you need to access the JSON response.
并json_body在您需要访问 JSON 响应时使用。
For example, inside your request spec you can use it directly
例如,在您的请求规范中,您可以直接使用它
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
回答by Clinton
Another approach to test just for a JSON response (not that the content within contains an expected value), is to parse the response using ActiveSupport:
另一种仅测试 JSON 响应(不是其中的内容包含预期值)的方法是使用 ActiveSupport 解析响应:
ActiveSupport::JSON.decode(response.body).should_not be_nil
If the response is not parsable JSON an exception will be thrown and the test will fail.
如果响应不可解析 JSON,则会抛出异常并且测试将失败。
回答by Kevin Trowbridge
You could look into the 'Content-Type'header to see that it is correct?
您可以查看'Content-Type'标题以查看它是否正确?
response.header['Content-Type'].should include 'text/javascript'
回答by Koen.
When using Rails 5 (currently still in beta), there's a new method, parsed_bodyon the test response, which will return the response parsed as what the last request was encoded at.
当使用 Rails 5(目前仍处于测试阶段)时,有一个新方法,parsed_body在测试响应上,它将返回解析为最后一个请求编码的响应。
The commit on GitHub: https://github.com/rails/rails/commit/eee3534b
GitHub 上的提交:https: //github.com/rails/rails/commit/eee3534b
回答by Damien Roche
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:
如果您想利用 Rspec 提供的散列差异,最好解析正文并与散列进行比较。我发现的最简单的方法:
it 'asserts json body' do
expected_body = {
my: 'json',
hash: 'ok'
}.stringify_keys
expect(JSON.parse(response.body)).to eql(expected_body)
end

