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
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"
The simple controller testing code works in a SQL backend rails application, but not in the mongodb backend rails application.
require 'test_helper'
class PostsController < ActiveController::TestCase
test "should get index" do
get :index
assert_response :success
end
end
While running rake --verbose test, no normal successful output and it exits & prints nothing.
Any clue what might be wrong?
I have figured out the root cause of the problem. When require "rails/test_unit/railtie" is added to config/application.rb, the test can be run without problem.
While following Michael Hartl's Rails tutorial, I was experimenting with some custom functions in my test section, and ran into a restriction that surprised me. Basically, global path variables (eg "root_path") only work within the "do...end" block of an "it" section within a "describe" block of the RSpec tests.
I believe the following details boil down to the question, what is special about the "it" block which enabled "root_path" to work there while not working outside of the "it" block?
(I've determined a workaround, but I'm curious whether there's a solid explanation of this behavior.)
File: spec/requests/static_pages_spec.rb
This fails:
require 'spec_helper'
def check_stable(path)
it "should be stable" do
get path
response.status.should be(200)
end
end
describe "StaticPages" do
describe "Home => GET" do
check_stable(root_path)
end
end
This succeeds:
require 'spec_helper'
describe "StaticPages" do
describe "Home => GET" do
it "should be stable" do
get root_path
response.status.should be(200)
end
end
end
The failure is basically:
$ bundle exec rspec spec/requests/static_pages_spec.rb
Exception encountered: #<NameError: undefined local variable or method `root_path' for #<Class:0x00000004cecd78>>
... any idea why?
I tried all of the suggestions on these two threads:
Hartl's Tutorial Section 5.3.2: Rails Routes
Rspec and named routes
None worked until I sussed out the issue above.
Yes, named routes work only within it or specify blocks. But it's easy to modify the code:
def should_be_stable(path)
get path
response.status.should be(200)
end
describe "StaticPages" do
describe "Home => GET" do
it { should_be_stable(root_path) }
end
end
You steel need to include url_helpers
it blocks (or specify blocks) are what denote actual tests. Inside a test, you will have access to the full complement of Rails and Rspec helpers; outside the test, not so much (as you have worked out).
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
I'm facing some problems when trying to assert that a method in a Mongoid::Document class is invoked by my controller code:
require 'spec_helper'
describe AController do
describe 'GET index' do
it 'returns the full list' do
get :index
Model.should_receive(:find).with(:all)
response.code.should eq ("200")
end
end
end
Looking at test.log i can see the the query being executed against the database. BUT, the test fails with rspec complaining that Model.find(:all) was expected once, but received 0 times. Anyone got an idea of what is happening here? It seems to me that Rspec is not being able to stub classes that include Mongoid::Document.
Thanks!
Sorry, i screwed up, the expectation was supposed to be set before the get
Correct way:
Model.should_receive(:find).with(:all)
get :index
response.code.should eq ("200")