RSpec controller spec: How to test rendered JSON?
I'm trying to test a simple controller's action of a Rails API
Here's the controller in question:
class Api::TransactionsController < ApplicationController
def index
transactions = Transaction.all
json = TransactionSerializer.render(transactions)
render json: json
end
end
Here are my specs so far
require 'rails_helper'
RSpec.describe Api::TransactionsController do
describe '.index' do
context "when there's no transactions in the database" do
let(:serialized_data) { .to_json }
before { allow(TransactionSerializer).to receive(:render).with().and_return(serialized_data) }
after { get :index }
specify { expect(TransactionSerializer).to receive(:render).with() }
specify { expect(response).to have_http_status(200) }
end
end
end
I want to test the response. Something like in this Stack Overflow question How to check for a JSON response using RSpec?:
specify { expect(response.body).to eq(.to_json) }
My problem is that response.body
is an empty string. Why is that ?
ruby-on-rails ruby rspec rspec-rails
add a comment |
I'm trying to test a simple controller's action of a Rails API
Here's the controller in question:
class Api::TransactionsController < ApplicationController
def index
transactions = Transaction.all
json = TransactionSerializer.render(transactions)
render json: json
end
end
Here are my specs so far
require 'rails_helper'
RSpec.describe Api::TransactionsController do
describe '.index' do
context "when there's no transactions in the database" do
let(:serialized_data) { .to_json }
before { allow(TransactionSerializer).to receive(:render).with().and_return(serialized_data) }
after { get :index }
specify { expect(TransactionSerializer).to receive(:render).with() }
specify { expect(response).to have_http_status(200) }
end
end
end
I want to test the response. Something like in this Stack Overflow question How to check for a JSON response using RSpec?:
specify { expect(response.body).to eq(.to_json) }
My problem is that response.body
is an empty string. Why is that ?
ruby-on-rails ruby rspec rspec-rails
What is it that you are expecting inresponse.body
? Also, better practice to haveexpect(response).to have_http_status(:success)
.
– Aaditya Maheshwari
Dec 27 '18 at 18:29
1
Because your database intest
environment is empty.
– Aleksei Matiushkin
Dec 27 '18 at 18:49
Yes the database is empty, so the response should be an empty array. Besides as you can see in the specs, I stubbed the serializer to return an empty array.
– David B.
Dec 27 '18 at 19:50
2
I think that you need to callget :index
in abefore
block, otherwise there is not response body.
– eikes
Dec 27 '18 at 20:54
Yes it works and it makes sense. thanks
– David B.
Dec 27 '18 at 21:28
add a comment |
I'm trying to test a simple controller's action of a Rails API
Here's the controller in question:
class Api::TransactionsController < ApplicationController
def index
transactions = Transaction.all
json = TransactionSerializer.render(transactions)
render json: json
end
end
Here are my specs so far
require 'rails_helper'
RSpec.describe Api::TransactionsController do
describe '.index' do
context "when there's no transactions in the database" do
let(:serialized_data) { .to_json }
before { allow(TransactionSerializer).to receive(:render).with().and_return(serialized_data) }
after { get :index }
specify { expect(TransactionSerializer).to receive(:render).with() }
specify { expect(response).to have_http_status(200) }
end
end
end
I want to test the response. Something like in this Stack Overflow question How to check for a JSON response using RSpec?:
specify { expect(response.body).to eq(.to_json) }
My problem is that response.body
is an empty string. Why is that ?
ruby-on-rails ruby rspec rspec-rails
I'm trying to test a simple controller's action of a Rails API
Here's the controller in question:
class Api::TransactionsController < ApplicationController
def index
transactions = Transaction.all
json = TransactionSerializer.render(transactions)
render json: json
end
end
Here are my specs so far
require 'rails_helper'
RSpec.describe Api::TransactionsController do
describe '.index' do
context "when there's no transactions in the database" do
let(:serialized_data) { .to_json }
before { allow(TransactionSerializer).to receive(:render).with().and_return(serialized_data) }
after { get :index }
specify { expect(TransactionSerializer).to receive(:render).with() }
specify { expect(response).to have_http_status(200) }
end
end
end
I want to test the response. Something like in this Stack Overflow question How to check for a JSON response using RSpec?:
specify { expect(response.body).to eq(.to_json) }
My problem is that response.body
is an empty string. Why is that ?
ruby-on-rails ruby rspec rspec-rails
ruby-on-rails ruby rspec rspec-rails
edited Dec 27 '18 at 19:50
Aaditya Maheshwari
383211
383211
asked Dec 27 '18 at 18:10
David B.
182211
182211
What is it that you are expecting inresponse.body
? Also, better practice to haveexpect(response).to have_http_status(:success)
.
– Aaditya Maheshwari
Dec 27 '18 at 18:29
1
Because your database intest
environment is empty.
– Aleksei Matiushkin
Dec 27 '18 at 18:49
Yes the database is empty, so the response should be an empty array. Besides as you can see in the specs, I stubbed the serializer to return an empty array.
– David B.
Dec 27 '18 at 19:50
2
I think that you need to callget :index
in abefore
block, otherwise there is not response body.
– eikes
Dec 27 '18 at 20:54
Yes it works and it makes sense. thanks
– David B.
Dec 27 '18 at 21:28
add a comment |
What is it that you are expecting inresponse.body
? Also, better practice to haveexpect(response).to have_http_status(:success)
.
– Aaditya Maheshwari
Dec 27 '18 at 18:29
1
Because your database intest
environment is empty.
– Aleksei Matiushkin
Dec 27 '18 at 18:49
Yes the database is empty, so the response should be an empty array. Besides as you can see in the specs, I stubbed the serializer to return an empty array.
– David B.
Dec 27 '18 at 19:50
2
I think that you need to callget :index
in abefore
block, otherwise there is not response body.
– eikes
Dec 27 '18 at 20:54
Yes it works and it makes sense. thanks
– David B.
Dec 27 '18 at 21:28
What is it that you are expecting in
response.body
? Also, better practice to have expect(response).to have_http_status(:success)
.– Aaditya Maheshwari
Dec 27 '18 at 18:29
What is it that you are expecting in
response.body
? Also, better practice to have expect(response).to have_http_status(:success)
.– Aaditya Maheshwari
Dec 27 '18 at 18:29
1
1
Because your database in
test
environment is empty.– Aleksei Matiushkin
Dec 27 '18 at 18:49
Because your database in
test
environment is empty.– Aleksei Matiushkin
Dec 27 '18 at 18:49
Yes the database is empty, so the response should be an empty array. Besides as you can see in the specs, I stubbed the serializer to return an empty array.
– David B.
Dec 27 '18 at 19:50
Yes the database is empty, so the response should be an empty array. Besides as you can see in the specs, I stubbed the serializer to return an empty array.
– David B.
Dec 27 '18 at 19:50
2
2
I think that you need to call
get :index
in a before
block, otherwise there is not response body.– eikes
Dec 27 '18 at 20:54
I think that you need to call
get :index
in a before
block, otherwise there is not response body.– eikes
Dec 27 '18 at 20:54
Yes it works and it makes sense. thanks
– David B.
Dec 27 '18 at 21:28
Yes it works and it makes sense. thanks
– David B.
Dec 27 '18 at 21:28
add a comment |
1 Answer
1
active
oldest
votes
Not sure what kind of serializer you're using. But, render
is not a method on an ActiveModel::Serializer
. Try this instead:
module Api
class TransactionsController < ApplicationController
def index
transactions = Transaction.all
render json: transactions
end
end
end
If your TransactionSerializer
is an ActiveModel::Serializer
, Rails will, by convention, just use it to serialize each Transaction record in the ActiveRecord::Relation
.
And, test it like this:
require 'rails_helper'
describe Api::TransactionsController do
describe '#index' do
context "when there's no transactions in the database" do
let(:transactions) { Transaction.none }
before do
allow(Transaction).to receive(:all).and_return(transactions)
get :index
end
specify { expect(response).to have_http_status(200) }
specify { expect(JSON.parse(response.body)).to eq() }
end
end
end
Part of the problem here might have been that you weren't actually calling get :index
until after
the tests ran. You need to call it before the tests run.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53949148%2frspec-controller-spec-how-to-test-rendered-json%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
Not sure what kind of serializer you're using. But, render
is not a method on an ActiveModel::Serializer
. Try this instead:
module Api
class TransactionsController < ApplicationController
def index
transactions = Transaction.all
render json: transactions
end
end
end
If your TransactionSerializer
is an ActiveModel::Serializer
, Rails will, by convention, just use it to serialize each Transaction record in the ActiveRecord::Relation
.
And, test it like this:
require 'rails_helper'
describe Api::TransactionsController do
describe '#index' do
context "when there's no transactions in the database" do
let(:transactions) { Transaction.none }
before do
allow(Transaction).to receive(:all).and_return(transactions)
get :index
end
specify { expect(response).to have_http_status(200) }
specify { expect(JSON.parse(response.body)).to eq() }
end
end
end
Part of the problem here might have been that you weren't actually calling get :index
until after
the tests ran. You need to call it before the tests run.
add a comment |
Not sure what kind of serializer you're using. But, render
is not a method on an ActiveModel::Serializer
. Try this instead:
module Api
class TransactionsController < ApplicationController
def index
transactions = Transaction.all
render json: transactions
end
end
end
If your TransactionSerializer
is an ActiveModel::Serializer
, Rails will, by convention, just use it to serialize each Transaction record in the ActiveRecord::Relation
.
And, test it like this:
require 'rails_helper'
describe Api::TransactionsController do
describe '#index' do
context "when there's no transactions in the database" do
let(:transactions) { Transaction.none }
before do
allow(Transaction).to receive(:all).and_return(transactions)
get :index
end
specify { expect(response).to have_http_status(200) }
specify { expect(JSON.parse(response.body)).to eq() }
end
end
end
Part of the problem here might have been that you weren't actually calling get :index
until after
the tests ran. You need to call it before the tests run.
add a comment |
Not sure what kind of serializer you're using. But, render
is not a method on an ActiveModel::Serializer
. Try this instead:
module Api
class TransactionsController < ApplicationController
def index
transactions = Transaction.all
render json: transactions
end
end
end
If your TransactionSerializer
is an ActiveModel::Serializer
, Rails will, by convention, just use it to serialize each Transaction record in the ActiveRecord::Relation
.
And, test it like this:
require 'rails_helper'
describe Api::TransactionsController do
describe '#index' do
context "when there's no transactions in the database" do
let(:transactions) { Transaction.none }
before do
allow(Transaction).to receive(:all).and_return(transactions)
get :index
end
specify { expect(response).to have_http_status(200) }
specify { expect(JSON.parse(response.body)).to eq() }
end
end
end
Part of the problem here might have been that you weren't actually calling get :index
until after
the tests ran. You need to call it before the tests run.
Not sure what kind of serializer you're using. But, render
is not a method on an ActiveModel::Serializer
. Try this instead:
module Api
class TransactionsController < ApplicationController
def index
transactions = Transaction.all
render json: transactions
end
end
end
If your TransactionSerializer
is an ActiveModel::Serializer
, Rails will, by convention, just use it to serialize each Transaction record in the ActiveRecord::Relation
.
And, test it like this:
require 'rails_helper'
describe Api::TransactionsController do
describe '#index' do
context "when there's no transactions in the database" do
let(:transactions) { Transaction.none }
before do
allow(Transaction).to receive(:all).and_return(transactions)
get :index
end
specify { expect(response).to have_http_status(200) }
specify { expect(JSON.parse(response.body)).to eq() }
end
end
end
Part of the problem here might have been that you weren't actually calling get :index
until after
the tests ran. You need to call it before the tests run.
answered Dec 28 '18 at 6:14
aridlehoover
1,367912
1,367912
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53949148%2frspec-controller-spec-how-to-test-rendered-json%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
What is it that you are expecting in
response.body
? Also, better practice to haveexpect(response).to have_http_status(:success)
.– Aaditya Maheshwari
Dec 27 '18 at 18:29
1
Because your database in
test
environment is empty.– Aleksei Matiushkin
Dec 27 '18 at 18:49
Yes the database is empty, so the response should be an empty array. Besides as you can see in the specs, I stubbed the serializer to return an empty array.
– David B.
Dec 27 '18 at 19:50
2
I think that you need to call
get :index
in abefore
block, otherwise there is not response body.– eikes
Dec 27 '18 at 20:54
Yes it works and it makes sense. thanks
– David B.
Dec 27 '18 at 21:28