I'm trying to get a deeper understanding about how RSpec and Rails loads files, more than solving this specific issue.
My rails application has a common structure, with a new folder:
my_app/
/assets
/controllers
/...
/services (new folder)
/spec
In the spec folder I have a test. At this moment, it only tests the creation of a new instance of my class
require 'rails_helper'
RSpec.describe MyClass do
context 'something' do
it 'does something' do
instance = MyClass.new
end
end
end
MyClass is a bit special, because in it's constructor a dependency from other of my classes is injected:
class MyClass
def initialize(dependency = MyDependency.new)
@dependency = dependency
end
end
And to make it a bit more complicated, MyDependency belongs to a group of common classes, that inherits from a base class:
require 'my_base'
class MyDependency < MyBase
end
This code fails with the following exception:
Failure/Error: instance = MyClass.new
NoMethodError:
undefined method `value' for nil:NilClass
My test is in the same folder than spec_helper.rb. This helper starts with:
ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
I don't understand what is the mechanism that allows RSpec to access the rails files, and also my services folder. It should consider, MyClass, MyBase and finally MyDependency.
RSpec relies on Rails and Ruby autoloading and Rails and Ruby autoloading is explained in http://urbanautomaton.com/blog/2013/08/27/rails-autoloading-hell/. Autoloading may be unrelated to the error you showed above, however. To understand what's happening there, you should look at and (if you're interested in help) share the backtrace and associated code (e.g. what is calling .value
).