Correct way to test lib folder with rspec? - ruby-on-rails

I have a test that tries to test a class located in lib folder.
Right now I do this in my parser_spec.rb
require 'spec_helper'
require 'parser' --> Because my class is /lib/parser.rb
describe "parser" do
it "needs a url to initialize" do
expect { Parser.new }.to raise_error(ArgumentError)
end
end
What would be the correct way to include all the lib files, so that they are in the scope of the rspec tests?

The way you've done it -- require 'parser' is the recommended way. RSpec puts lib on the $LOAD_PATH so that you can require files relative to it, just like you've done.

Try this
require_relative "../../lib/parser.rb"
or
require 'lib/parser.rb'
rspec automatically loads 'spec/spec_helper.rb' when it runs, and it also automatically adds the 'lib' folder to it's LOAD_PATH, so that your requires in 'lib/parser.rb' are seen and required properly.

Just put the 'lib' folder to autoload_path. For example, in application.rb
config.autoload_paths += "#{Rails.root}/lib/"
Then you can do it normally
require 'spec_helper'
describe Parser do
...
end

In order to avoid lib autoload as Ryan Bigg said, you can autoload a custom directory placed in the app root:
Into /your/config/application.rb you can add:
config.autoload_paths += %W(#{config.root}/my_stuff)
Then, you can do:
require 'spec_helper'
describe Parser do
#your code...
end
Maybe, you can put your class inside a module in order to avoid collisions:
class MyStuff::Parser
#your code...
end
Then, you can do:
require 'spec_helper'
describe MyStuff::Parser do
#your code...
end

Related

Loading file from model to spec

I want to load my model file into spec. When i try to require 'project' in my spec it does not work. How can i load my model file inside spec.
require File.dirname(__FILE__) + '/project.rb'
RSpec.describe Project do
it 'finds an project' do
project = class_double("project")
end
end
The above statement tries to load model from spec directory... but i want to load model file which inside app directory.
You can try:
require Rails.root.join("app", "models", "project.rb")

Rspec not loading support files

I have this file:
# support/auth_macros.rb
module AuthMacros
def login_user
before(:each) do
#request.env["devise.mapping"] = Devise.mappings[:user]
#logged_in_user = FactoryGirl.create(:user, username: "logged_in")
sign_in #logged_in_user
end
end
def logout_user
before(:each) do
sign_out #logged_in_user
end
end
end
In my spec_helper file, I have this line:
Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f }
Yet when I run rspec, I get errors like:
undefined local variable or method `login_user' for RSpec::ExampleGroups::PostsController::POSTCreate::WhenSignedIn:Class
The relevant function is located in support/auth_macros, which I assume would be picked up by the require statement in my spec_helper.
Any idea what might be going on?
You have required the file, but the method is wrapped inside a module. You need to either remove the wrapping module or include it within your group test.
Update:
To be 100% specific: require loads the file and do nothing else. After file is required, the module has been created, but it is not included. You need to include it with: include AuthMacros
If your file relative path like support/auth_macros.rb and you wanna load it on selenium_helper.rb file, you need to do both step bellow:
Call require to load the file: require 'support/auth_macros'
And include it using: include AuthMacros
Hope it help.

Rails autoloading behaves strangely in RSpec with modules and subclasses with spork

In my Rails app I've added the following files:
app/models/baz.rb
lib/presenters/foo_presenter.rb
lib/presenters/foo_presenter/bar.rb
spec/models/baz_spec.rb
spec/lib/presenters/foo_presenter/bar_spec.rb
The contents of lib/presenters/foo_presenter.rb is something like:
module Presenters
module FooPresenter
def self.render
# do stuff
end
end
end
The contents of lib/presenters/foo_presenter/bar.rb is like:
module Presenters
class FooPresenter::Bar
def baz
# do stuff
end
end
end
The contents of spec/lib/presenters/foo_presenter/bar_spec.rb is like:
require 'spec_helper'
module Presenters::FooPresenter
describe Bar do
# some tests
end
end
Then I have a spec file in spec/models/baz_spec.rb:
require 'spec_helper'
describe Baz do
it 'works' do
Presenters::FooPresenter.render
end
end
(The contents of app/models/baz.rb is not relevant to this issue)
The problem is when I run rspec spec/models/baz_spec.rb it works fine without spork, but when spork is running, I get an error like:
NameError: undefined method `render' for Presenters::FooPresenter:Module
I traced through the code a bit and noticed that when rspec loads spec/lib/presenters/foo_presenter/bar_spec.rb it causes Rails to autoload lib/presenters/foo_presenter/bar.rb and so at that point Presenters::FooPresenter::Bar is loaded, but then when baz_spec.rb runs, lib/presenters/foo_presenter.rb has never been loaded and thus the exception. But this only happens if spork is running. The quick fix was to require 'foo_presenter' in a file in config/initializers, but is there a cleaner solution that doesn't need the explicit require? My guess is the issue here is that Rails doesn't autoload lib/presenters/foo_presenter.rb because Presenters::FooPresenter has already been defined by bar_spec.rb.
A co-worker and I were faced with this problem today and we eventually found we needed Spork to reload the classes on every run. We used the each_run() method to do this:
Spork.each_run do
Dir[Rails.root.join("app/classes/**/*.rb")].each {|f| require f}
end

Can't figure out how to include a certain file in Rails/RSpec

I have the following code in lib/test/company.rb:
module Test
class Company
# irrelevant stuff
end
end
In spec/model/request.rb, I've tried all of the following:
require "company"
require "lib/test/company"
require "lib/test/company.rb"
require Rails.root + "/lib/test/company.rb"
None of those works, at the class certainly isn't getting autoloaded. What's going on?
In your spec file:
require "test/company"
This is unnecessary if you'd like to autoload all modules/classes from lib. To do so, add to the config block in your application.rb file:
module YourApp
class Application < Rails::Application
config.autoload_paths += %W( #{config.root}/lib )
end
end
Addition:
You can then call Test::Company from the top-level namespace to access this class.
Try require "#{Rails.root}/lib/test/company.

testing rails engine generator with rspec

I create a simpe gem wich include a install generator, generator works fine but now I want to test it using rspec, I foud this gem, and try to test my generator, my spec code is:
require 'genspec'
require 'rosalie'
describe :install_generator do
it "should generate model" do
subject.should generate("message.rb")
end
end
rosalie is the name of may gem, now when I run it I got an error:
/stuff/work/my_projects/rosalie/lib/rosalie/engine.rb:2:in `': uninitialized constant Rosalie::Rails (NameError)
my engine.rb code is:
module Rosalie
class Engine < Rails::Engine
initializer "rosalie.models.messageable" do
ActiveSupport.on_load(:active_record) do
include Rosalie::Models::Messageable
end
end
end
end
anybody can help me with this problem?
You have to load your code before you include it somewhere.
Either require or autoload your main file.
Here is an example from my gem.
You need add these code in your spec_helper.rb, and require the spec_helper in each spec.
require File.expand_path("../dummy/config/environment", __FILE__)
require 'rspec/rails'

Resources