I have some controllers that are in subdomains of the controllers folder.
for example, i have a controller in app/controllers/api/v1/offers_controller.rb that looks like this:
class Api::V1::OffersController < ApplicationController
respond_to :json
def index
...some code here
end
end
I tried putting a controller in spec/controllers/api/v1/offers_controller.rb that looks like this:
require 'spec_helper'
descripe Api::V1::OffersController do
describe "GET 'index'" do
it "returns http success" do
get 'index'
response.should be_success
end
end
end
however, when I run rspec spec, this test does not get run at all. I also tried putting it in the spec/controllers directory, named api_v1_offers_controller.rb, and the test is still not run.
How can I write RSpec tests for these types of controllers?
It actually seems it was a mistake it how I named the file. it seems all RSpec tests need to end it _spec
Related
I am trying to run basic controller test.
My controller_spec.rb looks like:
class Test < ActionController::Base
def test_meth
puts 'hello for test meth'
head 200
end
end
describe Test do
it 'responds with 200' do
get :test_meth
expect(response.status).to eq(200)
end
end
When I run this spec I end up with an error
ActionController::UrlGenerationError: No route matches {:action=>"test_meth", :controller=>"test"}
I am not sure if I am missing something very basic here becasue this looks very straight forward. Any help is much appreciated.
The error is clear, in your routes.rb file you have not written the action correctly.
You must have.
get "test", to: "test#test_meth"
So I am pretty new to testing with RSPEC
I am just testing the rendering of my controller like so:
describe "GET job" do
it "renders the jobs view" do
get :jobs
expect(response).to render_template :jobs
end
However my view (jobs) is a folder, not a template so the above dosnt work. How do i test to see if the response is going to the jobs view folder. inside my jobs view folder i have many different files.
My customer controller action looks like so:
def jobs
#jobs = #customer.jobs
end
To test that the template foobar inside app/views/jobs/ is rendered you should use this code:
describe "GET job" do
it "renders the jobs view" do
get :jobs
expect(response).to render_template :foobar
end
If you are not testing JobsController and would like to make sure that it still renders app/views/jobs/foobar then you should change it to this line:
expect(response).to render_template("jobs/foobar")
Ideally, in rspec controller test view rendering has been stubbed by default. To check view rendering in controller specs you have to do as follows:
describe "GET job" do
render_views
it "renders the jobs view" do
get :jobs
expect(response).to render_template("jobs/foobar")
end
where render_views will make render respective views of a controller action.
Given I set up a HomeController with an index action
class HomeController < ApplicationController
def index
#users = User.all
end
end
and routed to it via the root path,
root :to => "home#index"
why does this request spec fail
it 'should called the home#index action' do
HomeController.should_receive(:index)
visit root_path
end
with the following message
Failure/Error: HomeController.should_receive(:index)
(<HomeController (class)>).index(any args)
expected: 1 time
received: 0 times
? Is it because the index method is called as a instance method instead of a class method?
I'm not sure exactly what you want to test, and I think there's some confusion as to what methods can be used where, so I'll try and give examples of Routing specs, Request Specs, Controller specs, and Feature specs, and hopefully one of them will be appropriate for you.
Routing
If you want to make sure that your root path gets routed to the home#index action, a routing spec may be appropriate:
spec/routing/routing_spec.rb
describe "Routing" do
it "routes / to home#index" do
expect(get("/")).to route_to("home#index")
end
end
Request
If you want to make sure that the index template gets rendered on a request to your root path, a request spec may be appropriate:
spec/requests/home_requests_spec.rb
describe "Home requests" do
it 'successfully renders the index template on GET /' do
get "/"
expect(response).to be_successful
expect(response).to render_template(:index)
end
end
Controller
If you want to make sure that the index template gets rendered on a request to the index action of your HomeController, a controller spec may be appropriate (and quite similar to a request spec in this case, but focused exclusively on the controller):
spec/controllers/home_controller_spec.rb
describe HomeController do
describe "GET index" do
it "successfully renders the index template" do
expect(controller).to receive(:index) # this line probably of dubious value
get :index
expect(response).to be_successful
expect(response).to render_template(:index)
end
end
end
Feature
If you want to make sure the page rendered by home#index has some specific content, a feature spec may be appropriate (and also the only place you can use Capybara methods like visit, depending on your Rails/RSpec version):
spec/features/home_features_spec.rb
feature "Index page" do
scenario "viewing the index page" do
visit root_path
expect(page).to have_text("Welcome to my awesome index page!")
end
end
class MyController < ApplicationController
def index
my_method
end
def my_method
end
end
describe MyController do
it 'calls my method' do
expect(controller).to receive(:my_method)
get :index
end
end
Hello and thanks for you patience!
My rails app uses a combination of rspec and shoulda to run tests. The tests are automated over guard and spork. One of my controllers tests looks like
it {should respond_with(:success)}
When running tests i get
Expected response to be a 200, but was 301
manually testing by browsing & wget things go right, the page is responding correctly with 200 status code. As I am quite new to rails testing, proberly I am not understanding how the tests are currently ran. How are they implemented? What was the purpose of the environment 'test'? Is there some kind of webserver running in backgroud to run the tests? Obviously there is some kind of non-wanted redirecting.
Thanks in advance!
Edit: More sources
controller:
class PlansController < ApplicationController
def index
#plans=Plan.all
end
... more methods ...
end
test:
describe PlansController do
before :each do
#plan=FactoryGirl.create(:plan)
end
context " get :index" do
before do
get :index
end
it {should respond_with(:success)}
end
... more tests..
end
You are missing an :each in the before block of the context for get :index so you are never calling the index action.
Update as follows:
context " get :index" do
before(:each) do
get :index
end
it { should respond_with(:success) }
end
I'm doing some tests here using Rspec and I would like to assure that the controller is calling the log method in some actions. I'm also using mocha.
I would like something like this:
it "update action should redirect when model is valid" do
Tag.any_instance.stubs(:valid?).returns(true)
put :update, :id => Tag.first
controller.expects(:add_team_log).at_least_once
response.should redirect_to(edit_admin_tag_url(assigns[:tag]))
end
is there something to use as the 'controller' variable? I tried self, the controller class name...
I just got helped with this. For testing controllers, you'd nest your specs inside a describe which names the controller. (The spec should also be in the Controllers folder)
describe ArticlesController do
integrate_views
describe "GET index" do
...
it "update action should redirect when model is valid" do
...
controller.expects(:add_team_log).at_least_once
...
end
end
end
I think you want #controller instead of controller. Here's an example from my test suite:
it "delegates to the pricing web service" do
isbn = "an_isbn"
#controller.expects(:lookup)
.with(isbn, anything)
.returns({asin: "an_asin"})
get :results, isbn: isbn
assert_response :success
end