The below rspec test is not passing, I'm not sure what I'm doing wrong. It routes fine in the browser, but the test is not passing.
require 'spec_helper'
describe QueueVideosController do
describe "GET show" do
context "with authenticated users" do
it "routes /queue to the QueueVideos controller" do
expect(get("/queue")).to route_to("queue_videos#show")
end
end
end
end
From my controller:
class QueueVideosController < ApplicationController
def show
end
end
From my routes file:
get '/queue' => 'queue_videos#show'
Try using a different syntax:
expect(get: "/queue").to route_to(
controller: "queue_videos",
action: "show"
)
Related
I'm trying to write a controller test which tests a subdomain constraint. However, I'm unable to get RSpec to set the subdomain and return an error if the subdomain isn't accurate.
I'm using Rails 4.2.6 and RSpec ~3.4
routes.rb
namespace :frontend_api do
constraints subdomain: 'frontend-api' do
resources :events, only: [:index]
end
end
events_controller.rb
module FrontendAPI
class EventsController < FrontendAPI::BaseController
def index
render json: []
end
end
end
spec
RSpec.describe FrontendAPI::EventsController do
describe 'GET #index' do
context 'wrong subdomain' do
before do
#request.host = 'foo.example.com'
end
it 'responds with 404' do
get :index
expect(response).to have_http_status(:not_found)
end
end
end
end
Is there some other way of doing this?
You can accomplish this by using the full URL in your tests instead of setting the host in a before block.
Try:
RSpec.describe FrontendAPI::EventsController do
describe 'GET #index' do
let(:url) { 'http://subdomain.example.com' }
let(:bad_url) { 'http://foo.example.com' }
context 'wrong subdomain' do
it 'responds with 404' do
get "#{bad_url}/route"
expect(response).to have_http_status(:not_found)
end
end
end
end
There is a similar question and answer here testing routes with subdomain constraints using rspec
So I don't have a great reason for needing to know this other than curiosity - the BEST reason - but I'm not sure what's going on here.
Background:
I'm working through the RSpec book and updating the examples.
On Chapter 24 - Rails Controllers there's a test for a messages controller.
## spec/controllers/messages_controller_spec.rb ##
require 'spec_helper'
describe MessagesController do
describe "POST create" do
let(:message) { mock_model(Message).as_null_object }
before do
Message.stub(:new).and_return(message)
end
# Then a bunch of Tests...
context "when the message fails to save" do
before do
message.stub(:save).and_return(false)
post :create
end
it "assigns #message" do
assigns[:message].should eq(message)
end
it "renders the new template" do
response.should render_template("new")
end
end
end
end
This goes along with the messages controller:
## app/controllers/messages_controller.rb ##
class MessagesController < ApplicationController
def create
#message = Message.new(params[:message])
if #message.save
flash[:notice] = "The message was saved successfully"
redirect_to action: "index"
else
render "new"
end
end
end
When I run the tests:
The test passes with response.
it "renders the new template" do
response.should render_template("new")
end
The test also passes with subject.
it "renders the new template" do
subject.should render_template("new")
end
The test Also passes with page
it "renders the new template" do
page.should render_template("new")
end
The test ALSO passes with NOTHING
it "renders the new template" do
should render_template("new")
end
In case it helps anyone make heads or tails of this, the config/routes.rb just has resources :messages
Why do all those tests pass? What am I actually testing? Are 'page', 'subject', and ' ' just synonyms for response?
Does it matter as long as my tests pass?
By default, the subject would be referencing the class, which is the MessagesController.
Not defining a subject in the last test example, will implicitly set the subject to be MessagesController.
From a binding.pry, it appears that subject is an instance of the controller class:
[2] pry(#<RSpec::ExampleGroups::MyController::DescribeString::ContextString>)> subject.is_a? Class
=> false
[3] pry(#<RSpec::ExampleGroups::MyController::DescribeString::ContextString>)> subject.is_a? Users::SessionsController
=> true
I'm writing tests with rspec for my application controller in my rails app (written in Rails 4) and I'm running into a problem where it doesn't recognize the route for the HTTP request I'm sending. I know there's a way to do this using MyApp::Application.routes but I'm not able to get it working.
#application_controller_spec.rb
require 'spec_helper'
class TestController < ApplicationController
def index; end
end
describe TestController do
before(:each) do
#first_user = FactoryGirl.create(:user)
# this is to ensure that all before_filters are run
controller.stub(:first_time_user)
controller.stub(:current_user)
end
describe 'first_time_user' do
before(:each) do
controller.unstub(:first_time_user)
end
context 'is in db' do
before(:each) do
#user = FactoryGirl.create(:user)
controller.stub(:current_user).and_return(#user)
end
it 'should not redirect' do
get :index
response.should_not be_redirect
end
end
context 'is not in db' do
context 'session[:cas_user] does not exist' do
it 'should return nil' do
get :index
expect(assigns(:current_user)).to eq(nil)
end
end
it "should redirect_to new_user_path" do
controller.stub(:current_user, redirect: true).and_return(nil)
get :index
response.should be_redirect
end
end
end
The error I'm getting right now is
No route matches {:action=>"index", :controller=>"test"}
I would add the test#index route to config/routes.rb, but it doesn't recognize the Test Controller, so I want to do something like
MyApp::Application.routes.append do
controller :test do
get 'test/index' => :index
end
end
but I'm not sure where to add this or if this even works in rspec. Any help would be great!
If you are trying to test your ApplicationController, see this RSpec documentation about it. You will need to define methods like index inside the test, but it works well.
I am attempting to create a RSpec controller test for a namespaced controller, but rspec doesn't seem able to detect the nesting and generate the proper path for the post :create action.
This is my spec code:
# for: /app/controllers/admin/crm/report_adjustments_controller.rb
require 'spec_helper'
describe Admin::Crm::ReportAdjustmentsController do
render_views
before(:each) do
signin
end
describe "GET 'index'" do
it "returns http success" do
get :index
response.should be_success
end
end
describe "POST 'create'" do
it "creates with right parameters" do
expect {
post :create, report_adjustment: {distributor_id: #ole_distributor.id, amount: "30.0", date: Date.today }
}.to change(Crm::ReportAdjustment, :count).by(1)
response.should be_success
end
end
end
# routes.rb
namespace :admin do
namespace :crm do
resources :report_adjustments
end
end
For this code, the get :index works just fine, but when post :create is called, the following error is generated: undefined method 'crm_report_adjustment_url'
Why would RSpec be smart enough to figure things out with get :index, but not with post :create? How do I get RSpec to properly load the right route, which is admin_crm_report_adjustments_url?
Thanks in advance.
Try posting to the url instead:
post admin_crm_report_adjustments_url
# or
post "/admin/crm/report_adjustments"
So I have read how to solve this problem:
RSpec Test of Custom Devise Session Controller Fails with AbstractController::ActionNotFound
and
http://lostincode.net/blog/testing-devise-controllers
But under which file do I add these changes is my problem:
Under the rspec folder for my
registrations_controller
I tried this
before :each do
request.env['devise.mapping'] = Devise.mappings[:user]
end
require 'spec_helper'
describe RegistrationsController do
describe "GET 'edit'" do
it "should be successful" do
get 'edit'
response.should be_success
end
end
end
Which didn't work, any help with the specific files to change to make this work would be greatly appreciated.
EDIT
So I also tried -
https://github.com/plataformatec/devise/wiki/How-To:-Controllers-and-Views-tests-with-Rails-3-(and-rspec)
so I made a folder with spec/support and made a file called controllers_macros.rb
module ControllerMacros
def login_admin
before(:each) do
#request.env["devise.mapping"] = Devise.mappings[:admin]
sign_in Factory.create(:admin) # Using factory girl as an example
end
end
def login_user
before(:each) do
#request.env["devise.mapping"] = Devise.mappings[:user]
user = Factory.create(:user)
user.confirm! # or set a confirmed_at inside the factory. Only necessary if you are using the confirmable module
sign_in user
end
end
end
And my registrations_controller is now this:
require 'spec_helper'
describe RegistrationsController do
describe "GET 'edit'" do
before :each do
request.env['devise.mapping'] = Devise.mappings[:user]
end
it "should be successful" do
get 'edit'
response.should be_success
end
end
end
I have other controllers in rspec do I need to change every single one? Or I'm confused on where to make the changes.
Just take the first version you tried, but move the before block inside the first describe block like this:
require 'spec_helper'
describe RegistrationsController do
before :each do
request.env['devise.mapping'] = Devise.mappings[:user]
end
describe "GET 'edit'" do
it "should be successful" do
get 'edit'
response.should be_success
end
end
end