I am using rspec-rails-3 and my version of rails is 4.0.2. I have mongodb database. While i am trying to run rspec tests, i am getting error
Failure/Error: ext_wiki = Entity.find_by(name_ref:'dev_extraction for wikipedia')
Optionable::Unknown:
:consistency is an unknown option. Valid options are: :write, :read, :database, :max_retries, :pool_size, :retry_interval, :refresh_interval, :down_interval, :ssl, :timeout, :instrumenter, :auto_discover.
I have a Entity named model. Code in entity_spec.rb is as follows -:
require 'rails_helper'
RSpec.describe Entity, :type => :model do
it "checks old and new code" do
ext_wiki = Entity.find_by(name_ref:'dev_extraction for wikipedia')
ext_wiki1 = Entity.find_by(name_ref:'dev_extraction for wikipedia')
expect(ext_wiki1['code']).to eq(ext_wiki['code'])
end
it "gives pass" do
expect(1).to eq(1)
end
end
Your Mongoid configuration (mongoid.yml) has an option (consistency) which is not a valid option. The 4.0.0 changelog says:
The :consistency option is no longer valid, use the :read option now.
Even I change consistency to :read, it didn't work. What I did is I remove the line "consistency: :strong" line from mongoid.yml
Related
I have a simple test but the describe keyword is not working in Sorbet tests.
The error I'm receiving on these methods:
Method `describe` does not exist on `T.class_of(<root>)`7003
RSpec.describe(Model) do
describe 'my test' do
before(:each) do # .before error
user = FactoryBot.create(:user)
end
it 'can fill in all fields' do # .it errors
end
end
end
I think I need to tell Sorbet some how that this is called in the context of spec_helper.rbbut I'm not sure how to do that.
I've already installed this gem rspec-sorbet and ran
spec/spec_helper.rb
require 'rspec/sorbet'
To silence the errors, I ran this:
RSpec.describe(Model) do
T.bind(self, T.untyped)
# T.bind(self, RSpec) This does not work either
end
I'm trying this gem called FactoryBotRails. For some reason, when I try it on one of my models unit tests, the following error is thrown.
Failure/Error: my_model = build(:my_model)
NoMethodError:
undefined method `build' for #\<\RSpec::ExampleGroups::MyModel::ValidationTests:0x000055c553959958>
I don't know what I'm doing wrong, as long as I have followed several tutorials on the web, and did the same steps.
Added, in:
gemfile
gem 'factory_bot_rails', '~> 5.1.1'
app/spec/support/factory_bot.rb
RSpec.configure do |config|
config.include FactoryBot::Syntax::Methods
end
spec/rails_helper.rb
Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f }
spec/factories/my_models.rb
FactoryBot.define do
factory :my_model do
name { 'some name' }
code { 'some code' }
end
end
And used it like:
my_model = build(:my_model)
What is wrong with my configuration?
The issue might not be what you're calling, but where you're calling it. my_model = build(:my_model) is not syntax you want to use while writing specs, and the error message looks maybe you're calling it from outside of a spec? Because if you're calling it from within a spec, the error should be something along the lines of ArgumentError: Factory not registered: my_model. The spec itself should look like this:
# spec/models/my_model_spec.rb
require 'rails_helper'
describe MyModel do
let(:my_model) { build :my_model }
it { expect(my_model).to be_valid }
end
I would also specify the model name in your factory declaration (i.e., factory :my_model, class: 'MyModel' do). If you want to play with your factories, you can start up a test console:
# start rails console in 'test' environment
rails console test
my_model = FactoryBot.build :my_model
Note that you will need to use FactoryBot.build instead of build in your test console.
If this doesn't resolve your issue, please update your post with the contents of the spec you're trying to run, how you're trying to run it, and expand your definition of your spec/rails_helper.rb file. Since you're new to RSpec, I also suggest checking out http://www.betterspecs.org/ for best practices.
Probably you're missing to setup shortcuts for FactoryGirl by including its methods in your rails_helper:
RSpec.configure do |config|
# ...
config.include FactoryGirl::Syntax::Methods
end
The syntax for creation of factorybot is:
FactoryBot.create :my_model
Pass arguments hash if you need something different:
FactoryBot.create :my_model, name: "John Doe"
For multiple (e.g. 10 my_models):
FactoryBot.create_list :my_model, 10
I followed codeschool tutorial, but I encountered some troubles.
Here is zombie_spec.rb
#spec/model/zombie_spec.rb
require 'spec_helper'
require 'zombie'
describe Zombie do
it 'is invalid without a name' do
zombie = Zombie.new
zombie.should_not be_valid
end
end
zombie.rb
#spec/zombie.rb
class Zombie < ActiveRecord::Base
validates :name, presence: true
...
end
After I typed rspec spec/models/zombie_spec.rb, it throw uninitialized constant ActiveRecord (NameError)
I've put this project on github
I think the tutorial might be trying to transition from using RSpec on a plain Ruby object to using the rspec-rails gem on an ActiveRecord object. For the examples that use rspec-rails, you should have a model in the file app/models/zombie.rb. This is what the spec in spec/models/zombie_spec.rb will look for. Also, your specs will need to require rails_helper rather than spec_helper.
# app/models/zombie.rb
class Zombie < ActiveRecord::Base
validates :name, presence: true
def hungry?
true
end
end
# spec/models/zombie_spec.rb
require 'rails_helper'
describe Zombie do
it 'is invalid without a name' do
zombie = Zombie.new
zombie.should_not be_valid
end
end
Zombie is extending ActiveRecord::Base but your code can't find ActiveRecord.
To fix that you can require 'activerecord' within zombie.rb. Depending on whether or not it's installed, you may need to also gem install activerecord from your command line or, alternatively, add gem 'activerecord' to your Gemfile and run bundle install
I found an example that worked well for me:
require 'rails_helper'
RSpec.describe Auction, :type => :model do
it "is valid with valid attributes"
it "is not valid without a title"
it "is not valid without a description"
it "is not valid without a start_date"
it "is not valid without a end_date"
end
I am new to ruby, so I am not 100% sure why it needs this ":type" attribute, but it fixed my problem.
(Source)
I'm writing a typical test in my application where I create a model through a form and check that the model count equals 1.
The test fails because there are already multiple records in the test DB, and this count increases each time I run my tests. It looks like each example isn't happening inside a transaction (being rolled back) like it's supposed to, and I don't know why.
I have this line in my spec_helper.rb file, which is supposed to run each example in a transaction:
config.use_transactional_fixtures = true
Here is my spec that keeps generating model objects:
require 'spec_helper'
describe "Admin artwork pages" do
subject { page }
let(:gallery) { FactoryGirl.create(:gallery) }
describe "artwork creation" do
context "with valid attributes" do
it "creates new artwork" do
visit admin_gallery_artworks_path(gallery_id: gallery.id)
click_link 'Add new artwork'
fill_in 'artwork_title', with: 'Still Life'
click_button 'Create Artwork'
page.should have_text 'Successfully created'
Artwork.count.should eq 1
end
end
end
end
Here's the error message from Rspec:
Failures:
1) Admin artwork pages artwork creation with valid attributes creates new artwork
Failure/Error: Artwork.count.should eq 1
expected: 1
got: 153
(compared using ==)
Edit: Contents of my spec_helper.rb file:
ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require 'rspec/autorun'
require 'capybara/rails'
require 'capybara/rspec'
Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
RSpec.configure do |config|
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
config.fixture_path = "#{::Rails.root}/spec/fixtures"
# If you're not using ActiveRecord, or you'd prefer not to run each of your
# examples within a transaction, remove the following line or assign false
# instead of true.
config.use_transactional_fixtures = true
# If true, the base class of anonymous controllers will be inferred
# automatically. This will be the default behavior in future versions of
# rspec-rails.
config.infer_base_class_for_anonymous_controllers = false
# Run specs in random order to surface order dependencies. If you find an
# order dependency and want to debug it, you can fix the order by providing
# the seed, which is printed after each run.
# --seed 1234
config.order = "random"
# Include route helpers
config.include Rails.application.routes.url_helpers
#
# Take the FactoryGirl out of FactoryGirl.create
config.include FactoryGirl::Syntax::Methods
end
I'm using Rails 4.0.0.rc1, Ruby 1.9.3, FactoryGirl and rspec-rails 2.13.0 Thanks for any help.
It turns out that Rails 4 is supported starting in rspec-rails 2.13.1 - I was using 2.13.0. After upgrading, the specs took place within a transaction like they were supposed to.
Thanks to everyone who took the time to post help.
I believe the problem is the way you have your test written and less to due with config.use_transactional_fixtures = true. Focus on the bottom of the error that says (compared using ==)
Try to use the expecting change rspec syntax instead
Change this:
click_button 'Create Artwork'
page.should have_text 'Successfully created'
Artwork.count.should eq 1
To this:
expect { click_button 'Create Artwork' }.to change { Artwork, :count }.by(1)
page.should have_text 'Successfully created'
Let me know if this helps
You're running a request spec: when you call visit the code under test is run in a server instance (in the same process). In particular this means that it's using a different thread.
As a result the application code ends up using a different database connection, and since transactions are a per connection thing there is no transaction used when your controller inserts records into the database.
There are several ways to address this. One is to abandon rspec's transactional fixtures and use the database_cleaner gem. You can set it up so that controller and model specs use transactions but request specs use truncate to forcibly clear out tables.
Another approach is to try and force both the spec code and the server code to use the same database connection, this eliminating the problem. You can see this approach in this answer. In my experience this works pretty well until you start using a capybara driver such as poltergeist which will run any javascript on the page and your page fires ajax requests.
The approach I've been using is to set the active record connection pool size to 1: there is only 1 connection allowed so everyone will use the same one. You do then have to do some work to ensure that connections are returned to the pool or your spec just hangs.
I wrote up the details a while ago as a blog post, but in a nutshell you need to
call ActiveRecord::Base.clear_active_connections! before calling methods like visit, click and so on
hack config.middleware.insert_before ActiveRecord::ConnectionAdapters::ConnectionManagement so that it clears the connection after each request (by default it doesn't do this in tests).
I'd like to put a few integration tests in a separate directory from my controller unit specs. However, when I move my spec file to spec/integration, it fails with:
ArgumentError:
bad argument(expected URI object or URI string)
The spec passes correctly when in the spec/controllers directory.
Here's a bit from my spec:
require 'spec_helper'
describe Users::LoginsController, type: :controller do
let!(:user) { User.create(email: 'test#test.com', password: 'test')
it 'logs in the user' do
post :create, email: 'test#test.com', password: 'test'
controller.current_user.should == user
end
end
I'm using Rails 3.1.3, RSpec 2.7.0.
Are there any tricks I have to use to achieve this?
Try specifying type:
describe ProductsController, type: :controller do
it 'can test #show' do
get :show
end
end
Works in Rails 3.2.11
You have to do the following:
describe Users::LoginsController do
controller_name 'users/logins'
... the rest of your spec here ...
end
I am not entirely certain about the nested syntax, but at least you need to specify the controller_name to get it to work.
Hope this helps.
The test framework does not like it if you specify the test action using a symbol.
it 'logs in the user' do
post :create, email: 'test#test.com', password: 'test'
controller.current_user.should == user
end
becomes
it 'logs in the user' do
post 'create', email: 'test#test.com', password: 'test'
controller.current_user.should == user
end
I had the same problem and ended up simply using the URL
get "/users"
It's not as clean but gets the job done. I couldn't get the other suggestions to work.
This approach works for me in Rails 4 and RSpec 2.14.7:
My findings:
Don't name your directory integration. I need to grep through the source of either RSpec or Rails, but it appears to have an adverse effect on running controller specs. Perhaps someone with this knowledge can chime in to confirm this.
Name it something other than integration; in my case I tried int, which resulted in problems until I added the "type: :controller" after the #describe method.
After that, I was able to move all of my slow Rails specs into my int directory, allowing me to create a unit directory for all of my decoupled, fast specs.
Please let me know if this works for you.
By the way, I am running:
Ruby 1.9.3
Rails 4.0.2
rspec-core 2.14.7
rspec-rails 2.14.1
all on Mac OS X.
Take the opportunity now to get rid of your controller and integration specs. They're needlessly painful to write and too coupled to implementation. Replace them with Cucumber stories. Your life will be much easier...