Testing Application Controller - Rails - ruby-on-rails

How should I test this method on my ApplicationController:
def success
render nothing: true, status :ok
end
I've tried using controller.call(:success), but it returns an error.
Any ideas ?
Additional Info:
I'm using rspec

I would test it like this:
it 'responds with success' do
expect(response).to be_success
end
it 'renders nothing' do
expect(response).to render_template(nil)
end

Related

How to get rspec coverage for the failure of .save

In my controller I have the following code:
def create
#post = Post.new(post_params)
if #post.save
flash[:notice] = "#{#post.title} was successfully created."
redirect_to post_path
else
flash[:alert] = #post.errors.full_messages
render :new
end
end
I've managed to write rspec code to cover the true statement within a feature spec, however I am struggling for the false statement. So far this is the rspec I have come up with to solve my problem (placed in posts_controller_spec.rb):
it 'should return false and render the new template' do
allow_any_instance_of(Post).to receive(:valid?).and_return(false)
expect(response).to render_template(:new)
end
Unfortunately, I am met with the following error:
Failures:
1) PostsController create should return
Failure/Error: expect(response).to render_template(:new)
expecting <"new"> but rendering with <[]>
I've tried looking at other questions on stackoverflow as well as other suggestions online, but can't seem to figure it out.
Any help would be much appreciated :)
In your test, you never call the controller.
it 'renders the new template' do
allow_any_instance_of(Post).to receive(:valid?).and_return(false)
post :create, params: {...}
expect(response).to render_template(:new)
end
It would be more direct to do receive(:save).and_return(false).
However, there's no need for a mock here. Send invalid Post parameters.
context 'when the Post params are invalid' do
let(:params) do
{
post: { something: "invalid" }
}
end
it 'does not make a Post, renders the new template, and flashes an error' do
expect {
post :create, params: params
}.to change {
Post.count
}.by(0)
expect(response).to render_template(:new)
expect(flash[:alert]).not_to be_empty
end
end

Rails how to fix malformed request (error code 400)?

I am running RSpec for api, specifically to create posts (I am also working on :update and :destroy, but those two are running fine. I am having trouble with :create)
Here are my RSpec:
describe "POST create" do
before { post :create, topic_id: my_topic.id, post: {title: #new_post.title, body: #new_post.body} }
it "returns http success" do
expect(response).to have_http_status(:success)
end
it "returns json content type" do
expect(response.content_type).to eq 'application/json'
end
it "creates a topic with the correct attributes" do
hashed_json = JSON.parse(response.body)
expect(hashed_json["title"]).to eq(#new_post.title)
expect(hashed_json["body"]).to eq(#new_post.body)
end
end
And here is my create
def create
post = Post.new(post_params)
if post.valid?
post.save!
render json: post.to_json, status: 201
else
render json: {error: "Post is invalid", status: 400}, status: 400
end
end
Here is the error code that I keep getting:
.........F.F....
Failures:
1) Api::V1::PostsController authenticated and authorized users POST create returns http success
Failure/Error: expect(response).to have_http_status(:success)
expected the response to have a success status code (2xx) but it was 400
# ./spec/api/v1/controllers/posts_controller_spec.rb:78:in `block (4 levels) in <top (required)>'
I am really not sure what is wrong with the code. The routes work fine. How can I make the tests pass?
For a better solution tha #spickermann suggested, change post to #post in your #create action and add the code below to your specs and work from there. I bet you have to do something like #post.user = current_user in your controller.
it "#post is valid and have no errors" do
expect(assigns[:post]).to be_valid
expect(assigns[:post].errors).to be_empty
end

rspec devise-confirmable render 'devise/mailer/confirmation_instructions'

I have a devise confirmable on my user model, and I have tests on custom registrations_controller.
One of tests is like
it 'renders :new template' do
post :create, user: valid_params
expect(response).to render_template(:new)
end
But there is error:
Failure/Error: expect(response).to render_template(:new)
expecting <"new"> but rendering with <["devise/mailer/confirmation_instructions"]>
How to get render of #new template?
It seems I got an error by myself. User just not created, so I got this error.

'undefined method' post with Rails and Rspec

Got stuck with:
' undefined method `post' for #<Class:0x000001058c0f68> (NoMethodError)'
on testing controller create action.
I'm using Rails 4, rpsec, and Factory Girl
Controller:
def create
#post = Post.new(post_params)
#post.user_id = current_user.id
if #post.save
flash[:success] = "Yay! Post created!"
redirect_to root_path
else
# flash[:error] = #post.errors.full_messages
render 'new'
end
end
Test:
describe '#create' do
post 'create', FactoryGirl.attributes_for(:post, user: #user)
response.should be_successful
end
I think post method is accessible inside it method block:
describe 'create' do
it 'should be successful' do
post :create, FactoryGirl.attributes_for(:post, user: #user)
response.should be_success
end
end
BTW I think you need to test for redirect, not success status.
Sorry for being off-topic but I just want to give you some advice.
Consider following best practices and use RSpec's expect syntax instead of should. Read more about why the should syntax is a bad idea here: http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
This is how I would rewrite your example:
describe 'create' do
it 'responds with 201' do
post :create, attributes_for(:post, user: #user)
expect(response.status).to eq(201)
end
end
In the example I'm using FactoryGirl's short syntax method attributes_for instead of FactoryGirl.attributes_for, it saves a few bytes. Here's how to make the short methods available (in spec/test_helper.rb):
RSpec.configure do |config|
config.include FactoryGirl::Syntax::Methods
end
I'm testing for the status code 201 which Rails will return by default for a successful create action (redirect should be 3xx).This makes the test more specific.
Hope it's any help for writing better specs.
The issue comes from the fact that post should be used inside an it statement. I usually test my controllers like this:
describe 'POST "create"' do
let(:user) { User.new }
let(:params) { FactoryGirl.attributes_for(:post, user: user) }
let(:action) { post :create, params }
let!(:post) { Post.new }
before do
Post.should_receive(:new).and_return(post)
end
context 'on success' do
before do
post.should_receive(:save).and_return(true)
end
it 'renders success' do
action
expect(response).to be_success
end
it 'redirects' do
action
expect(response).to be_redirected
end
it 'sets flash message' do
action
expect(flash[:success]).to_not be_empty
end
end
context 'on failure' do
before do
post.should_receive(:save).and_return(false)
end
it 'renders new' do
action
expect(response).to render_template(:new)
end
end
end

Rspec controller show test failing with rails 3.2.6

I have a simple rspec test which is failing after I upgrade to 3.2.6.
Here is the spec in users_controller_spec.rb
describe "show action" do
before(:each) do
User.stub!(:find).with(#user.id).and_return(#user)
end
def do_get
get :show, :id => #user.id
end
it "should be successful" do
do_get
response.should be_success
end
end
and here is the error
1) UsersController show action should be successful
Failure/Error: get :show, :id => #user.id
.........................
(class)> received :find with unexpected arguments
expected: (2)
got: ("2")
Not sure where is going wrong. The show action has nothing in the controller, it is just
def show
end

Resources