Integration tests with webrat and Rails3 - ruby-on-rails

I'm upgrading a Rails 2.3.5 app to Rails 3.0.3. But my integration tests
aren't working. I'm getting this error:
NoMethodError: undefined method `content_type' for nil:NilClass
The line to blame is
assert_select "input#artist.title.unsolved", 1
My test_helper.rb for webrat looks likes this:
require "webrat"
require 'webrat/core/matchers'
include Webrat::Methods
Webrat.configure do |config|
config.mode = :rack
end
I'm using shoulda 2.11.3 and webrat 0.7.3 for the testing. I've read,
that webrat and shoulda are compatible with Rails3.
Anyone an idea how to fix this?
Thanks!
tux
ADDITION:
It seems, that the NoMethodError appears from shoulda, not from Webrat, as mentioned in the title. Here is the trace:
NoMethodError: undefined method `content_type' for nil:NilClass
/Users/23tux/.rvm/gems/ruby-1.9.2-p136#rails3/gems/activesupport-3.0.3/lib/active_support/whiny_nil.rb:48:in `method_missing'
/Users/23tux/.rvm/gems/ruby-1.9.2-p136#rails3/gems/actionpack-3.0.3/lib/action_dispatch/testing/assertions/selector.rb:605:in `response_from_page_or_rjs'
/Users/23tux/.rvm/gems/ruby-1.9.2-p136#rails3/gems/actionpack-3.0.3/lib/action_dispatch/testing/assertions/selector.rb:213:in `assert_select'
test/integration/user_integration_test.rb:52:in `block (3 levels) in <class:UserIntegrationTest>'
/Users/23tux/.rvm/gems/ruby-1.9.2-p136#rails3/gems/shoulda-context-1.0.0.beta1/lib/shoulda/context/context.rb:412:in `call'
/Users/23tux/.rvm/gems/ruby-1.9.2-p136#rails3/gems/shoulda-context-1.0.0.beta1/lib/shoulda/context/context.rb:412:in `block in run_current_setup_blocks'
/Users/23tux/.rvm/gems/ruby-1.9.2-p136#rails3/gems/shoulda-context-1.0.0.beta1/lib/shoulda/context/context.rb:411:in `each'
/Users/23tux/.rvm/gems/ruby-1.9.2-p136#rails3/gems/shoulda-context-1.0.0.beta1/lib/shoulda/context/context.rb:411:in `run_current_setup_blocks'
/Users/23tux/.rvm/gems/ruby-1.9.2-p136#rails3/gems/shoulda-context-1.0.0.beta1/lib/shoulda/context/context.rb:393:in `block in create_test_from_should_hash'
And here is the whole block context around the assert_select:
class SongIntegrationTest < ActionController::IntegrationTest
context "a visitor" do
context "solving a song" do
setup do
#song = Song.make
visit song_path(#song)
end
should "have two guess fields" do
assert_select "input#artist.title.unsolved", 1
assert_select "input#title.title.unsolved", 1
end
Maybe the assert_select isn't longer available in Rails 3 with Shoulda.
Hope someone can help me!
thx!

There is a fork of webrat that works with rails3 at https://github.com/joakimk/webrat. At some point it should get pulled into the main branch. rails 2.3 is still very popular at this time.

Related

capybara have_title NoMethodError

At the moment, this is a simple project - just a couple of static pages. I'm developing a generic test framework but am struggling to differentiate between the different test options. I have added Rspec, Capybara, Faker, Factory Girl, Spring, and shoulda (though I'm not using the shoulda matchers at the moment).
I have this controller test file:
require 'rails_helper'
RSpec.describe StaticPagesController, type: :controller do
describe "GET #a_page" do
before(:each) { get :a_page }
it "returns http success" do
expect(response).to have_http_status(:success)
end
it "has a page title Static Site" do
expect(response).to have_title('Static Site')
end
end
end
When this runs through guard, it throws an error stack:
23:13:39 - INFO - Run all
23:13:39 - INFO - Running all specs
Running via Spring preloader in process 4498
Running via Spring preloader in process 4506
/home/steve/workspaces/static_site/db/schema.rb doesn't exist yet. Run `rake db:migrate` to create it, then try again. If you do not intend to use a database, you should instead alter /home/steve/workspaces/static_site/config/application.rb to limit the frameworks that will be loaded.
.F
Failures:
1) StaticPagesController GET #a_page has a page title Static Site
Failure/Error: expect(response).to have_title('Static Site')
NoMethodError:
undefined method `match' for nil:NilClass
Did you mean? catch
# /home/steve/.rvm/gems/ruby-2.3.1/gems/capybara-2.7.1/lib/capybara/queries/title_query.rb:18:in `resolves_for?'
# /home/steve/.rvm/gems/ruby-2.3.1/gems/capybara-2.7.1/lib/capybara/node/document_matchers.rb:20:in `block in assert_title'
# /home/steve/.rvm/gems/ruby-2.3.1/gems/capybara-2.7.1/lib/capybara/node/simple.rb:144:in `synchronize'
# /home/steve/.rvm/gems/ruby-2.3.1/gems/capybara-2.7.1/lib/capybara/node/document_matchers.rb:19:in `assert_title'
# /home/steve/.rvm/gems/ruby-2.3.1/gems/capybara-2.7.1/lib/capybara/rspec/matchers.rb:105:in `matches?'
# ./spec/controllers/static_pages_controller_spec.rb:34:in `block (3 levels) in <top (required)>'
# /home/steve/.rvm/gems/ruby-2.3.1/gems/spring-commands-rspec-1.0.4/lib/spring/commands/rspec.rb:18:in `call'
# /home/steve/.rvm/gems/ruby-2.3.1/gems/spring-1.7.1/lib/spring/command_wrapper.rb:38:in `call'
# /home/steve/.rvm/gems/ruby-2.3.1/gems/spring-1.7.1/lib/spring/application.rb:191:in `block in serve'
# /home/steve/.rvm/gems/ruby-2.3.1/gems/spring-1.7.1/lib/spring/application.rb:161:in `fork'
# /home/steve/.rvm/gems/ruby-2.3.1/gems/spring-1.7.1/lib/spring/application.rb:161:in `serve'
# /home/steve/.rvm/gems/ruby-2.3.1/gems/spring-1.7.1/lib/spring/application.rb:131:in `block in run'
# /home/steve/.rvm/gems/ruby-2.3.1/gems/spring-1.7.1/lib/spring/application.rb:125:in `loop'
# /home/steve/.rvm/gems/ruby-2.3.1/gems/spring-1.7.1/lib/spring/application.rb:125:in `run'
# /home/steve/.rvm/gems/ruby-2.3.1/gems/spring-1.7.1/lib/spring/application/boot.rb:19:in `<top (required)>'
# -e:1:in `<main>'
Finished in 0.029 seconds (files took 2.54 seconds to load)
2 examples, 1 failure
Failed examples:
rspec ./spec/controllers/static_pages_controller_spec.rb:33 # StaticPagesController GET #a_page has a page title Static Site
The first test runs OK and, without the second, I get a clean result. I've spent a lot of time going over my config and it looks OK. I have also looked at the docs and some support sites.
Can anybody help out?
Capybara matchers need to be called against a html/xml document element (or a string that parses into a document), not against a response object. By default Capybaras matchers are normally only available in feature and view specs (not controller) was there a particular reason you included them into controller specs? Verifying a pages title really should lean more towards being a view spec than controller (by default views aren't rendered in controller specs - https://www.relishapp.com/rspec/rspec-rails/docs/controller-specs).
As #Thomas Walpole pointed out, Capybara is not enabled in controller specs by default. One option is to change the type of the test to feature (type: :feature).
To make Capybara's built-in matcher have_title work, you need to use visit from Capybara's API, not get from ActionDispatch::IntegrationTest.

View specs have no render method

I’m trying to write some view specs that test some template logic. I’m following the instructions in the RSpec book, and also checking other online references. I don’t seem to have access to render or assign.
require "spec_helper"
describe "projects/index.html.erb" do
it "displays an entry for each project" do
projects = 5.times { FactoryGirl.create :project }
render
expect(all(".project-index-entry").count).to eq 5
end
end
When I run the above, I get:
Failure/Error: render
NameError:
undefined local variable or method `render' for #<RSpec::ExampleGroups::ProjectsIndexHtmlErb:0x007fa2950d4140>
# ./spec/views/projects/index.html.erb_spec.rb:7:in `block (2 levels) in <top (required)>'
The same thing happens if I try to use assign. I know I could use visit, but then I would have to simulate the act of the user signing in before each spec. I may be misunderstood, but I think the render method is meant to be more isolated, allowing me to skip the authentication check I have in the controller.
So, why don’t I have the view spec methods I was expecting?
Versions:
- capybara 2.4.1
- rails 4.1.0
- rspec-core 3.1.3
- rspec-expectations 3.1.1
- rspec-mocks 3.1.0
- rspec-rails 3.1.0
As it turns out, I updated rspec some time ago and the previous version used a significantly different spec_helper. After the update, the logic was split into spec_helper and rails_helper, so to fix this problem I had to rerun rails generate rspec:install.

Devise 3.2 + Rspec 3

I'm trying to build some tests with Rspec and I'm getting the following error:
Failure/Error: get :index
NoMethodError:
undefined method `authenticate!' for nil:NilClass
Then I made some searchs and I realized that I had to include this line in the spec_helper.rb:
RSpec.configure do |config|
config.include Devise::TestHelpers, type: :controller
end
It seems that this code worked for most people but not for me. Now i'm getting the following error:
/home/bruna/Dropbox/Rails/academico/spec/spec_helper.rb:18:in `block in <top (required)>': uninitialized constant Devise (NameError)
I think this might be some error in this version of rspec and/or devise. Has anyone seen this error? Please, help me :'(
RSpec 3 configuration is different from earlier versions, with the addition of a spec/rails_helper.rb file that must be included for each spec file. Add the Devise TestHelpers to the spec/rails_helper.rb file.
If you need more information about RSpec 3 configuration, I've written an RSpec Tutorial. There's also information about testing Devise with RSpec, including advice about session helpers for feature testing, in my Rails Devise Tutorial.

undefined method `get' with Rspec

I have a problem with a very basic Rspec code, the same problem as the question 'undefined method `get' for #'.
But in my case none of the solutions given have worked for me!
I have my Rspec code at '/RailsProject/spec/controllers' and the code is:
require "../spec_helper"
describe "ApiMobile", :type => :controller do
it "Log In" do
get 'apiMobile/v0/logIn/test'
expect(response).to be_success
end
end
As you can see I've followed all the instructions but I still have the problem:
1) ApiMobile Log In
Failure/Error: get 'apiMobile/v0/logIn/test'
NoMethodError:
undefined method `get' for #<RSpec::Core::ExampleGroup::Nested_1:0x000000023b5ec8>
# ./api_mobile_controller_spec.rb:6:in `block (2 levels) in <top (required)>'
Finished in 0.00056 seconds
1 example, 1 failure
I have missed something or similar?
Thanks!
I finally discovered what was happening: Peter Alfvin was right, the fault was the isntallation.
I added at the Gemfile 'gem rspec' and at the command line typed 'rspec --init' after the 'bundle install'. But I also needed to add the gem 'rspec-rails' and type 'rails generate rspec:install'.
Now the get command works (I have another error but I think that is related to routes).

rails 3.2 and machinist issues

I've just upgraded to Rails 3.2.1 with Ruby 1.9.3-p0 and I'm using Machinist 2.0. Before updating a large project all my tests passed. The problem I"m having is when I create a blueprint within a 'let' call in my rspec tests and then refer to it in a before do block.
let (:new_post) {Post.make!}
before do
Post.stub!(:new).and_return(new_post)
end
This used to work, and now I get the following error:
1) PostsController GET index assigns all posts as #posts
Failure/Error: let (:new_post) {Post.make!}
NoMethodError:
undefined method `title=' for nil:NilClass
# ./spec/support/blueprints.rb:22:in `block in <top (required)>'
# ./spec/controllers/posts_controller_spec.rb:37:in `block (2 levels) in <top (required)>'
# ./spec/controllers/posts_controller_spec.rb:40:in `block (2 levels) in <top (required)>'
Here is my blueprint:
require 'machinist/active_record'
Post.blueprint do
title {"Post"}
body {"hello world"}
end
For now my work around is to create them using instance variables within the before do block, but it would be nice to use the 'let' calls as it keeps my rspec tests cleaner.
Funny, I just ran across the exact same problem, although I'm on Rails 3.2.1, Machinist 2.0, and ruby 1.9.2-p290. I think there's a conflict between the execution of the Post.stub(:new) stub method and the Machinist make method, but I haven't dug into the code.
The best solution I've come up with is:
before do
new_post
Post.stub!(:new).and_return(new_post)
end
This will initialize the let (since let is lazy-loaded in rspec) before it gets to the stub method. It's hacky, but at least you (and I) can keep the let statement.

Resources