I created rails new --api whatever with:
gem 'rspec-rails', '~> 3.8'
in my Gemfile. Then, I created:
app/services/whatever_module/whatever_class.rb
and corresponding spec file:
spec/services/whatever_module/whatever_class_spec.rb
Now, when I run:
rspec services
I get this error:
NameError: uninitialized constant WhateverModule
How do I tell rspec to recognize the module by its spec path?
Your spec file should be in
spec/services/distamce/whatever_class_spec.rb.
In you case rspec tries to find the WhateverModule because of /whatever_module/ in your pathing for the spec file. You can try this to change to spec/services/foo_bar/whatever_class_spec.rb and you will get the missing FooBarModule error.
I think I figured out what you missed.
Rspec does not automatically require your app folder and so there are no modules or classes available from the app folder initially.
When you check https://github.com/rspec/rspec-rails#installation #2 then you can see you have to add some boilerplate files for rspec like rails_helper.rb and spec_helper.rb with rails generate rspec:install. These are responsible for all rspec related settings and the require of the app folder.
Also its required to add require 'rails_helper' on top of each spec file.
After you have done all this and you get the error Unable to autoload constant WhateverModule::WhateverClass then your whatever_class.rb has to look like this
module WhateverModule
class WhateverClass
end
end
Or you define the module in a file besides the whatever_module folder.
Related
I am using the default test for different purposes and I have decided to make a specific rspec environment configuration for running the test suite.
However, I discovered that upon changing to ENV["RAILS_ENV"] ||= rspec in my rails_helper.rb file, suddenly a LOT of things are going wrong, constants are not being loaded (FactoryGirl, DatabaseCleaner, etc. throw uninitialized constant errors)
My question is, where is the code that loads those guys in test environment ? Since I am planning to use this stage for other purposes than running automatic tests, I'm afraid this "out of nowhere" added configuration might not work well with what I am planning to do.
From the perspective of Rails, the test environment is configured and loaded like any other environment such as production or development. You can see this prefixing RAILS_ENV=test to many of the native Rails commands e.g. RAILS_ENV=test rails c will load the rails console for the test environment, and so on. Similarly, all test-specific configuration within Rails is defined in test.rb in your config/environments folder.
However, when you run your specs with rspec spec, you're actually starting the RSpec runner, which, for most intents and purposes, runs independently of Rails (even with the rspec-rails gem).
By convention, when RSpec starts the first thing it does is read command line args from the .rspec in the current directory, if it exists. Then it runs spec_helper.rb (and also rails_helper.rb for rspec-rails 3+). It's actually the spec_helper.rb which does all the heavy-lifting in loading the Rails environment for your tests, along with any of the modules you're using in tests, such as DatabaseCleaner, FactoryGirl, etc.
If you're wondering how RSpec hooks into Rails, the bulk of it is performed in this line, which bootstraps Rails.
require File.expand_path('../../config/environment', __FILE__)
Now, as to your question, without the ENV['RAILS_ENV'] ||= 'test' statement, the above line will load Rails in the default environment (development), which isn't what you want, since any gems not in the :test group will not be loaded, and environments/test.rb will not be loaded either.
TL;DR
Test configuration is handled by two files: spec/spec_helper.rb (sometimes named rails_helper.rb) and config/environments/test.rb. The former configures RSpec and any objects and modules which will be used specifically within the files used in spec, the latter configures your Rails app itself. Omitting ENV['RAILS_ENV'] ||= test loads the development environment and gemsets instead of the test environment and gemsets, which is why you're getting a ton of errors.
If you are getting uninitialized constant errors for FactoryGirl, DatabaseCleaner etc, you most likely included them to test group in your Gemfile.
You should move them to rspec group, eg:
# Gemfile
group :rspec do
gem 'factory_girl_rails', '~> 4.0'
gem 'faker'
end
I'm using the following:
Rails 4.1.1
guard-zeus 2.0.0
rspec-rails 3.0.1
Out of box default rails g rspec:install and guard init
When I run guard and save a spec file, I get the error:
undefined method `configure` for RSpec:Module (NoMethodError)
I can run specs with rspec spec and rake just fine.
In spec_helper, if I require 'rspec/rails before the configure block,
guard works fine, but then rspec spec fails with the error:
uninitialized constant ActiveSupport::Autoload (NameError)
I'm guessing there's a problem with load order now that rails_helper and spec_helper
are separated.
Two questions:
How can I fix this?
Is there a different solution for continuous integration locally that you can recommend that works with latest Rails and Rspec.
You only have to answer one question.
The following fix worked for me:
#spec/spec_helper.rb
require 'rspec/core'
Throwing out a quick answer that may be the problem. Your spec_helper file should have the following order:
ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
rspec/rails needs to be required after the config/environment require.
The following:
undefined method `configure` for RSpec:Module (NoMethodError)
suggests you are are missing a
require 'rspec'
This normally isn't necessary, but if you put it in your spec/spec_helper.rb that should work.
(If you run RSpec directly, it's included already with RSpec).
The reason it's not included is perhaps:
you are not running guard through bundler
or your Gemfile does not have:
gem 'rspec' # without the require: false
or something may be wrong with your .rspec file (which should be present)
The require 'rspec/rails' should probably go into the spec/rails_helper.rb...
... but a better way would be to update your rspec-rails gem and run:
rails generate rspec:install
and if you're prompted - used 'd' to differences (and ideally use the recommended changes).
You should add following require to top of file spec_helper.rb
require 'rspec/rails'
Take the reference here: Zeus GitHub issue 308
I just created a mountable engine. The test directory looks somewhat like this:
engine_name
-test
- dummy
- test_helper.rb
- models
-engine_name
-- user_test.rb
etc
I attempted to call 'rspec' -> didn't work. Error message stated it couldn't find the folder 'spec'
I then called 'rspec test' -> it found the directory, but didn't find the test.
Found that rspec looks for *_spec.rb files, so I renamed user_test.rb to user_spec.rb
rspec then found the file, but it said it couldn't find test_helper.rb (since that was required by user_spec.rb).
I have a feeling that this engine's test directory is not designed for rspec. What's the best way to test an engine?
Thanks!
Since you are using rspec, you should use the directory spec instead of test.
The test directory is the default for test unit.
If you run rspec and you have a spec directory it will grab the tests from there.
You need a right spec_helper.rb (test_helper.rb is for test unit). You can see the example of spec_helper.rb in the template from rspec-rails repository.
Then, you should require the spec_helper in the user_spec.rb and just run rspec in the terminal.
I'm using rspec 2.10 with Rails 3.2.1 and have problems with classes not being found.
I have put a class called DbTasks under a dir app/util. Under spec, i've created file util/db_tasks_spec.rb which runs afer i included the line:
require File.join(File.dirname(__FILE__), '../../app/util/db_tasks')
However, rspec now isn't able to find my models. I don't want to have to include these manually. Is there a way to config rspecs paths so everything gets found?
I started making a Rails 3.1 engine, and I'm having a hard time testing it using rspec.
First of all, if I run rails g integration_test whatever it creates a regular integration test in tests/integration instead of spec/requests (the rspec-rails gem is installed and required as a development dependency in the gemspec file)
Also, when I run a spec test I get an error saying the table corresponding to the model I'm testing has not been created. I tried rake engine_name:install:migrations and running rake db:migrate from inside the dummy app, and I get a "table already exists" error.
Everything just seems disconnected, I feel I'm missing something here to make the rspec gem work seamlessly as it usually does with full rails applications.
I followed all the changes from here http://rubyx.com/2011/03/01/start-your-engines and I can test the engine manually by launching the dummy app via the console as shown here http://railscasts.com/episodes/277-mountable-engines.
Is there a way to make rspec the default for testing a rails 3.1 engine?
I am using RSpec with a Rails engine without issues.
I created my plugin using the following switches: -T --full --dummy-path=spec/dummy.
-T excludes test/unit
--full indicates that the plugin is an engine
--dummy-path is simply so that we don't get a test directory (the
default is test/dummy).
From there I used the spec_helper from the "start your engines" article:
# Configure Rails Envinronment
ENV["RAILS_ENV"] = "test"
require File.expand_path("../dummy/config/environment.rb", __FILE__)
require 'rspec/rails'
ENGINE_RAILS_ROOT=File.join(File.dirname(__FILE__), '../')
# Requires supporting ruby files with custom matchers and macros, etc,
# in spec/support/ and its subdirectories.
Dir[File.join(ENGINE_RAILS_ROOT, "spec/support/**/*.rb")].each {|f| require f }
RSpec.configure do |config|
config.use_transactional_fixtures = true
end
For the generators. I add a config.generators block to my engine.rb file like so:
module MyEngine
class Engine < Rails::Engine
config.generators do |g|
g.test_framework :rspec, :view_specs => false
end
end
end
With that, I'm able to get rspec tests when running a generator like the model generator.
As for the DB, is your database.yml file set up correctly? Did you load the test environment, e.g. rake db:test:clone or rake db:migrate RAILS_ENV=test? My guess is that RSpec can't see your tables because there isn't a test database set up.
I was looking for the same answer and I found the combustion gem* which promise to setup a full environment for spec'ing your engine in a simpler way. Just add
gem.add_development_dependency 'combustion', '~> 0.3.1'
to your gemspec and run
bundle exec combust
to reproduce a full rails app in your spec directory.
*I haven't tried it yet...