rails 3.2 and machinist issues - ruby-on-rails

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.

Related

Gettting undefined method `empty?' for nil:NilClass in my test suite when I try to call a Rails path helper (*_path) using Rails, Rspec

Rails 6.1.3.1
Rspec
basic behavior spec code:
describe "index" do
it "should show me the list" do
visit dashboard_targets_path
end
end
the routes file
namespace :dashboard do
resources :targets
end
error shows me the exception, but strangely it appears as if it isn't calling through to the app, just fails right in my test code:
1) interaction for Dashboard::TargetsController index should show me the list
Failure/Error: visit dashboard_targets_path
NoMethodError:
undefined method `empty?' for nil:NilClass
# ./spec/system/dashboard/targets_behavior_spec.rb:16:in `block (3 levels) in <top (required)>'
# /Users/jason/.rvm/gems/ruby-2.6.6/gems/webmock-3.12.2/lib/webmock/rspec.rb:37:in `block (2 levels) in <main>'
# /Users/jason/.rvm/gems/ruby-2.6.6/gems/rspec-wait-0.0.9/lib/rspec/wait.rb:46:in `block (2 levels) in <main>'
it seems to be failing inside the test code, if I drop into the debugger there and run dashboard_targets_path directly I also get the same exception, so the problem is just using the helper within the TEST ENVIRONMENT
within the dev environment, this function works
the problem here was the the config/environments/test.rb file does have default_url_options.
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
when you hit errors that disappear into the Rails gems, a good way to debug them is like so:
begin
// your failing code here
rescue StandardError => e
puts e.backtrace
byebug
puts e.inspect
raise (e)
end
WARNING: do not leave this code in your app or check it in unless you explicitly want to use exception handling for flow control (not recommended!). This is recommended ONLY for debugging purposes.
here you will see the full backtrace to the line number in the Gem where it is failing. when debugging Gems be careful— remember to un-do any changes you make and know that your monkey-patching inside of the Gem code doesn't affect your production code.

How can I fix the "class variable ##debug_missing_translation of ActionView::Base is overtaken by Object" error when running any task with ruby 3.0?

I am trying to upgrade a Rails 6.1.3.1 application from Ruby 2.6.6 to 3.0.0
All the rspec tests run fine and the in development everything seems to work just fine except one thing:
Even the simplest of tasks fails with this error:
"class variable ##debug_missing_translation of ActionView::Base is overtaken by Object"
For example, this simpletask.rake file
task simpletask: :environment do
puts 'Hello'
end
is not able to run as I get the following error:
lxxx#xxx:~/Workspace/edumino$ rails simpletask
rails aborted!
class variable ##debug_missing_translation of ActionView::Base is overtaken by Object
/home/xxx/railsapp/config/environment.rb:5:in `<top (required)>'
/home/xxx/railsapp/bin/rails:5:in `require'
/home/xxx/railsapp/bin/rails:5:in `<top (required)>'
/home/xxx/railsapp/bin/spring:10:in `require'
/home/xxx/railsapp/bin/spring:10:in `block in <top (required)>'
/home/xxx/railsapp/bin/spring:7:in `<top (required)>'
Tasks: TOP => simpletask => environment
(See full trace by running task with --trace)
...so, it turns out the problem was an already existing task. I don't remember exactly why this was necessary but the task had this:
# frozen_string_literal: true
require "#{Rails.root}/app/helpers/cron_helper"
require "#{Rails.root}/app/helpers/notifier_helper"
require "#{Rails.root}/app/helpers/application_helper"
include ApplicationHelper
include ActionView::Helpers::TranslationHelper
include CronHelper
namespace :cron do
task sms: :environment do |_t, _args|
...
end
end
I assume that the guilty code was including the ActionView::Helpers::TranslationHelper
Again, I can't remember why I had to do that at that time. But if you bump into this kind of 'overtaken by' error when upgrading to Ruby 3.0, check your other tasks and see what kinda weird includes you might have had. In my case, since I didn't need the old task, I just removed it.

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.

Integration tests with webrat and Rails3

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.

Resources