I'm trying to use minitest (with rails 4.1.1 & ruby 2.0). For a the below spec, I'm getting an error:
it "is invalid when phone number too short" do
#contact.phone = "123456789"
assert_not #contact.valid?
end
1) Error:
Contact#test_0009_is invalid when phone number too short:
NoMethodError: undefined method `assert_not' for #<#<Class:0x007f8d6ac14608>:0x007f8d6b843488>
test/models/contact_test.rb:32:in `block (2 levels) in <top (required)>'
My dev & test for gem file has the following:
gem 'minitest-rails', '~> 2.0.1'
gem 'minitest', '~> 5.3.4'
By the way, I just upgraded to ruby 2.1.2 to no avail.
If available, please share with me clear documentation on setting rails 4 with minitest.
The assert_not method is added in ActiveSupport::TestCase, and is not present in vanilla Minitest tests. Most likely your test is not using ActiveSupport::TestCase. The easiest way to check is to add the following line to your test:
assert_includes self.class.ancestors, ActiveSupport::TestCase
The next question is why. I don't know what the rest of your test looks like so I can't say for sure. Whatever you are passing to the describe method isn't being matched to ActiveSupport::TestCase. New in minitest-rails 2.0 is the ability to match on an optional second parameter to describe. So an easy way to ensure ActiveSupport::TestCase is to provide :model.
describe "I'm not sure what you are doing here", :model do
it "is invalid when phone number too short" do
#contact.phone = "123456789"
assert_not #contact.valid?
end
end
Just found out that assert_not is only available inside ActiveSupport::TestCase when you use Spec it's not present
Related
I am using Rails 4.2.6, Ruby 2.2.1, rspec-rails 3.4.2, Grape 0.16.2, grape_token_auth 0.1.0. I installed apartment gem (1.0.2) for multitenancy and trying to write rspec tests for grape requests.
But I am getting the following error from rspec-rails response method every time irrespective of whatever solutions I tried.
#buf=["<!DOCTYPE html>\n<html>\n<head>\n <title>Apartment::TenantNotFound at /content/api/v1/questions</title>\n</head>\n<body>\n
The request is taking the host as 'www.example.com' all time. I tried so many solutions by googling it. But nothing works. you can see that in spec where I commented these lines. I want the url as 'http://g_m.lvh.me:3000' with the subdomain 'g_m'.
I tried this one:
https://github.com/influitive/apartment/wiki/Testing-Your-Application
But not works. I don't know why.
I tried this, but not working:
Rails: Wrong hostname for url helpers in rspec
and tried to set the host by:
host! "g_m.lvh.me:3000"
#request.host = 'g_m.lvh.me:3000'
request.host = 'g_m.lvh.me:3000'
Nothing works!
I created a test case like the following grape link says:
https://github.com/dblock/grape/commit/99bf4b44c511541c0e10f4506bf34ae9abcccd75
require 'rails_helper'
RSpec.describe ContentManager::QuestionAPI, :type => :request do
#before(:each) { Apartment::Tenant.switch!("g_m") }
#after(:each) { Apartment::Tenant.switch!("public") }
#before(:each) do
#begin
#client = FactoryGirl.create(:client, title: 'Sample title', subdomain: 'g_m')
#rescue
#client = Client.create!(title: 'Sample title', subdomain: 'g_m')
#end
#default_url_options[:host] = 'http://g_m.lvh.me:3000'
# request.host = "#{'g_m'}.lvh.me"
#end
#end
#before(:each) do
# if respond_to?(:default_url_options)
# default_url_options[:host] = 'http://g_m.lvh.me:3000'
# end
#end
describe "GET /content/api/v1/questions" do
it "returns an empty array of questions" do
get "/content/api/v1/questions"
#puts "response.inspect: #{response.inspect}"
response.status.should == 200
JSON.parse(response.body).should == []
end
end
end
My configurations:
in spec/rails_helper.rb
config.include RSpec::Rails::RequestExampleGroup, type: :request, file_path: /spec\/requests/
All time this request sent by rspec-rails with
url: '/content/api/v1/questions'
host: 'www.example.com'
My test result shows:
$ rspec spec/requests/
F
Failures:
1) ContentManager::QuestionAPI GET /content/api/v1/questions returns an empty array of questions
Failure/Error: response.status.should == 200
expected: 200
got: 500 (using ==)
# ./spec/requests/question_spec.rb:30:in `block (3 levels) in <top (required)>'
Deprecation Warnings:
Using `should` from rspec-expectations' old `:should` syntax without explicitly enabling the syntax is deprecated. Use the new `:expect` syntax or explicitly enable `:should` with `config.expect_with(:rspec) { |c| c.syntax = :should }` instead. Called from /home/vagrant/gauge-slcsl/spec/requests/question_spec.rb:30:in `block (3 levels) in <top (required)>'.
If you need more of the backtrace for any of these deprecations to
identify where to make the necessary changes, you can configure
`config.raise_errors_for_deprecations!`, and it will turn the
deprecation warnings into errors, giving you the full backtrace.
1 deprecation warning total
Finished in 6.19 seconds (files took 1.93 seconds to load)
1 example, 1 failure
Failed examples:
rspec ./spec/requests/question_spec.rb:26 # ContentManager::QuestionAPI GET /content/api/v1/questions returns an empty array of questions
abhi#ubuntu-trusty-64:~/my-app$
If anyone knows about the error and what I am doing wrong here, please reply/answer.
The error was because of, we have to say the apartment subdomain configuration that just exclude the 'www' word considering as a sub domain.
Add the following:
# config/initializers/apartment/subdomain_exclusions.rb
Apartment::Elevators::Subdomain.excluded_subdomains = ['www']
I was using the better_errors gem in my development and test environment. This causes the rspec output as an better error generated html codes and difficult to understand the rspec failure reason.
I removed better errors from 'test' environment and I got the clue of this error where we have to exclude the 'www' considering as a subdomain.
I generated the following scaffold (using Ruby 2.2.0, rails 4.1.8, postgres):
rails g scaffold Test user:references text:references data:hstore
In my test_spec.rb:
require 'rails_helper'
RSpec.describe Test, :type => :model do
describe 'User generates a test' do
before do
#text = create(:text, content: "Cats eat mice")
#user = create(:user)
#test = create(:test)
end
...
When I run rspec the test fails with the following message:
Failure/Error: #test = create(:test)
NoMethodError:
undefined method `new' for Test:Module
# ./spec/models/test_spec.rb:8:in `block (3 levels) in <top (required)>'
When I test other models (user, text) everything works well, only the Test model fails. Calling Test.create(...) in rspec file also fails. Creating new test in rails console works. Any ideas how to fix this?
With the default configuration, Rails defines the module constant Test, so Ruby doesn't autoload your test.rb file when FactoryGirl does a Test.new as part of your :test factory.
You can install Rails without the Test infrastructure by using the -T switch, in which case it won't define the Test module and you should be fine.
If Rails is already configured, you can put the following in your rails_helper.rb file to remove the Test constant and you should be ok as well:
Object.send(:remove_const, :Test)
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.
Facts:
Running my entire suite of specs will result in 21 consistent errors out of 610 specs.
If I run any individual spec file (for instance: messages_controller_spec.rb), they will all pass.
If I run any of the failed specs individually, they will each pass.
These errors are mostly ActionMailer failures, but some are otherwise.
One confusing aspect is that some of the specs fail because there was an extra row in the database than expected, while others fail because there was one less row than expected. That is, if it were a cleaning or cache issue, it seems like it should be consistently one more or one less.
I’m currently running Rails 4.1.1, Ruby 2.0.0p451, Rspec 2.14.8, Sidekiq via inline!
Gemfile(for test)
group :development, :test do
gem 'better_errors'
gem 'binding_of_caller'
gem 'faker'
gem 'guard-rspec'
gem 'pry'
gem 'rspec-rails'
gem 'spork-rails'
gem 'sqlite3'
gem 'thin'
end
group :test do
gem 'capybara'
gem 'capybara-email'
gem 'capybara-webkit'
gem 'database_cleaner'
gem 'fabrication'
gem 'launchy'
gem 'selenium-webdriver'
gem 'shoulda-matchers'
gem 'webmock'
gem 'vcr'
end
Please note, I’ve checked out about a dozen similar questions that did not work to fix this. So, to clarify:
I’m not using ARGV
I’m not using before(:all) - I use before(:each).
I have attempted Rails.cache.clear before both the :suite & the :each spec.
I have database cleaner set to :truncation for all cleaning (slower, but better results than :transaction - have had issues with reloading updated values using :transaction)
For convenience sake, maybe some examples will help:
scheduler_spec.rb (showing test that fails when whole suite is run)
require 'spec_helper'
require 'rake'
require 'sidekiq/testing'
Sidekiq::Testing.inline!
describe "scheduler", :vcr do
describe ":wipe_abandoned_images" do
let!(:abandoned_old_image) { Fabricate(:image) }
let!(:abandoned_young_image) { Fabricate(:image) }
let!(:adopted_image) { Fabricate(:image) }
let(:run_cleaner) do
Rake::Task[:wipe_abandoned_images].reenable
Rake.application.invoke_task :wipe_abandoned_images
end
before do
abandoned_young_image.update_columns(listing_id: nil, updated_at: 6.days.ago)
abandoned_old_image.update_columns( listing_id: nil, updated_at: 9.days.ago)
Rake.application.rake_require 'tasks/scheduler'
Rake::Task.define_task(:environment) #Stub env. Rspec runs the App, so dont want Rake to run it again.
end
context "for claimed images" do
it "leaves the image" do
adopted_image_id = adopted_image.id
run_cleaner
expect(Image.all.count ).to eq(2)
expect(Image.find(adopted_image_id) ).to be_present
end
end
end
end
Note that I'm using Sidekiq's inline! testing configuration on prior apps with good success & without this issue.
forgot_passwords_controller_spec.rb (showing test that fails when whole suite is run)
require 'spec_helper'
require 'sidekiq/testing'
Sidekiq::Testing.inline!
describe ForgotPasswordsController do
let!(:jen) { Fabricate(:user, email: 'jen#example.com') }
describe "POST create" do
context "with valid email provided" do
before { post :create, email: 'jen#example.com' }
after do
ActionMailer::Base.deliveries.clear
Sidekiq::Worker.clear_all
end
it 'sends the reset email to the users provided email' do
expect(ActionMailer::Base.deliveries.count).to eq(1)
end
end
end
end
Here's what happens when I run the specs in various ways:
ForgotPasswordsController Specs pass via RubyTest plugin in SublimeText2
2014-08-28T03:42:43Z 32968 TID-ov5g65p44 INFO: Sidekiq client with
redis options {} ........... Finished in 0.95479 seconds 11 examples,
0 failures Randomized with seed 40226 [Finished in 5.8s]
Scheduler Tests pass via RubyTest in SublimeText2
.Rationing out invitations to users... done. .Rationing out
invitations to users... done. ..Sweeping the server for abandoned
images... 2014-08-28T01:49:02Z 32426 TID-owjt9ggh8 INFO: Sidekiq
client with redis options {} done. .Sweeping the server for abandoned
images... done. .Sweeping the server for abandoned images... done.
.
Finished in 1.52 seconds 7 examples, 0 failures Randomized with seed
37996 [Finished in 8.6s]
Tests pass via rspec in Console
$ rspec ./spec/lib/tasks/scheduler_spec.rb
.Rationing out invitations to users... done. .Rationing out
invitations to users... done. ..Sweeping the server for abandoned
images... 2014-08-28T02:14:43Z 32456 TID-ouiui9g8c INFO: Sidekiq
client with redis options {} done. .Sweeping the server for abandoned
images... done. .Sweeping the server for abandoned images... done.
.
Finished in 1.32 seconds 7 examples, 0 failures Randomized with seed
19172
Tests fail when run entire suite of Rspec
These failures will pass if run individually or as the spec file they are from.
$ rspec
Finished in 49.71 seconds 610 examples, 21 failures, 10 pending
Failed examples:
Sometimes it has an extra value
13) scheduler :wipe_abandoned_images for abandoned images under 1
week old leaves the image
Failure/Error: expect(Image.all.count ).to eq(2)
expected: 2
got: 3
(compared using ==)
# ./spec/lib/tasks/scheduler_spec.rb:78:in `block (4 levels) in <top (required)>'
Sometimes it loses or doesn’t load a value
18) ForgotPasswordsController POST create with valid email provided
sends the reset email to the users provided email
Failure/Error: expect(ActionMailer::Base.deliveries.count).to eq(1)
expected: 1
got: 0
(compared using ==)
# ./spec/controllers/forgot_passwords_controller_spec.rb:22:in `block (4 levels) in <top (required)>'
Here's a list of the failures
rspec ./spec/controllers/messages_controller_spec.rb:161 # MessagesController POST create message about listing to user from guest with valid information with EXISTING, UN-confirmed guest with EXPIRED token sends another confirmation email with link to the guest
rspec ./spec/controllers/messages_controller_spec.rb:114 # MessagesController POST create message about listing to user from guest with valid information with NEW, UN-confirmed, and valid guest email sends an invitation for the guest to be put on safe-email list
rspec ./spec/controllers/invitations_controller_spec.rb:30 # InvitationsController POST create with valid email & available invitations sends an email
rspec ./spec/controllers/invitations_controller_spec.rb:33 # InvitationsController POST create with valid email & available invitations sends an email to the recipient_email address
rspec ./spec/controllers/users_controller_spec.rb:161 # UsersController POST create with invitation token in params with valid token & input confirmation email sending sends the email to the registering user
rspec ./spec/controllers/users_controller_spec.rb:158 # UsersController POST create with invitation token in params with valid token & input confirmation email sending sends the email
rspec ./spec/controllers/users_controller_spec.rb:164 # UsersController POST create with invitation token in params with valid token & input confirmation email sending sends an email with a confirmation link in the body
rspec ./spec/controllers/users_controller_spec.rb:354 # UsersController GET confirm_with_token with valid token has a welcome message in the email
rspec ./spec/controllers/users_controller_spec.rb:348 # UsersController GET confirm_with_token with valid token sends a welcome email
rspec ./spec/controllers/users_controller_spec.rb:351 # UsersController GET confirm_with_token with valid token sends the welcome email to the user
rspec ./spec/controllers/searches_controller_spec.rb:19 # SearchesController GET search GET search with specific category selected returns the matching OR partial-matching table row objects
rspec ./spec/controllers/searches_controller_spec.rb:22 # SearchesController GET search GET search with specific category selected only returns values from the selected category
rspec ./spec/lib/tasks/scheduler_spec.rb:75 # scheduler :wipe_abandoned_images for abandoned images under 1 week old leaves the image
rspec ./spec/lib/tasks/scheduler_spec.rb:68 # scheduler :wipe_abandoned_images for abandoned images over 1 week old deletes the images
rspec ./spec/lib/tasks/scheduler_spec.rb:84 # scheduler :wipe_abandoned_images for claimed images leaves the image
rspec ./spec/controllers/forgot_passwords_controller_spec.rb:24 # ForgotPasswordsController POST create with valid email provided sets the email subject to notify the user of the reset link
rspec ./spec/controllers/forgot_passwords_controller_spec.rb:27 # ForgotPasswordsController POST create with valid email provided sends the link with token in the body of the email
rspec ./spec/controllers/forgot_passwords_controller_spec.rb:21 # ForgotPasswordsController POST create with valid email provided sends the reset email to the users provided email
rspec ./spec/controllers/reset_passwords_controller_spec.rb:70 # ResetPasswordsController POST create with a valid token sets the email subject to notify the user of the reset password
rspec ./spec/controllers/reset_passwords_controller_spec.rb:67 # ResetPasswordsController POST create with a valid token sends a confirmation email to the user that their password has been changed
rspec ./spec/controllers/reset_passwords_controller_spec.rb:73 # ResetPasswordsController POST create with a valid token sends the link with token in the body of the email
I can't explain what is really causing the error. But it must due to setting the Sidekiq test mode globally. Remove the Sidekiq setting from the head section of the specs and try the following:
before do
Sidekiq::Testing.inline! do
post :create, email: 'jen#example.com'
end
end
after do
ActionMailer::Base.deliveries.clear
Sidekiq::Worker.clear_all
end
it 'sends the reset email to the users provided email' do
expect(ActionMailer::Base.deliveries.count).to eq(1)
end
Since I updated my Gemfile and moved to rspec 3, in many tests, I'm getting a error for: way:
it "should reject attribute that are too short" do
short = "a" * 3
hash = #attr.merge(:details => short)
Deal.new(hash).should have(1).error_on(:details)
end
I'm getting this error:
Failure/Error: Deal.new(hash).should have(1).error_on(:details)
NoMethodError:
undefined method `have' for #<RSpec::ExampleGroups::Deal_2::TestsOnDealsModelsValidations>
I read I should now be using "expect" instead of should but here with have(1).error_on, how should I write it to comply with rspec 3?
I tried the following but it still does not work:
it "should reject attribute that are too short" do
short = "a" * 3
hash = #attr.merge(:details => short)
expect(Deal.new(hash).error_on(:details).size).to eq(1)
end
I have replaced the likes of
Deal.new(hash).should have(1).error_on(:details)
with
deal = Deal.new(hash)
expect(deal.valid?).to be_falsey
expect(deal.errors[:details].size).to eq(1)
The first expectation with valid? is necessary as it initializes the errors list.
have and other similar matchers have been moved out of rspec core and into another gem, rspec-collection-matchers.
I recommend following the upgrade path from rspec 2 -> 3 as detailed in the rspec docs: https://relishapp.com/rspec/docs/upgrade
Upgrade to rspec 2.99
Run your test suite
Fix deprecation warnings
Upgrade to rspec 3.
If you had done this you would have received a deprecation error with your code that would have also told you what to do to fix it.
The line to add to your Gemfile should be:
gem 'rspec-collection_matchers'