ruby-on-railsrubyruby-on-rails-3rspecspork

NameError when running a rspec test in Spork


Getting a NameError when running a test in Spork. Test works find if I don't run it in Spork. (I am running Spork via RubyMine 6.0)

error is:

NameError: uninitialized constant FileMakerSync::FMStudent
./app/sync/file_maker_sync.rb:7:in `load_student'
./spec/sync/file_maker_sync_spec.rb:8:in `block (4 levels) in <top (required)>'

My spec is located in:

spec/sync/file_maker_sync_spec.rb

describe FileMakerSync do
  describe "..." do
    context "..." do
      before(:all) do
        @student = FileMakerSync.load_student('....')

      end
   ...
    end

  end
end

Which calls

/app/sync/file_maker_sync.rb

class FileMakerSync

  def self.load_student(student_id)
    fm_student = FMStudent.find_single(student_id: student_id)
  end
  ...
end

which calls

app/models/filemaker/fm_student.rb

class FMStudent < FMBase
  def as_local_model
  end
  ...
end

I gather the issue is that FMStudent isn't loaded correctly during Spork execution. Which I don't quite understand.

I am new to rails and don't quite get when to require 'filename' vs what is loadable by default. Also not what might be missing in spork setup.

I tried adding a require

require "app/models/filemaker/fm_student"
class FileMakerSync

but than I got this error

Exception encountered: #<LoadError: cannot load such file --     app/models/filemaker/fm_student>

Finally my spec_helper

require 'rubygems'
require 'spork'

Spork.prefork do

  if ENV["RUBYMINE_HOME"]
    $:.unshift(File.expand_path("rb/testing/patch/common", ENV["RUBYMINE_HOME"]))
    $:.unshift(File.expand_path("rb/testing/patch/bdd", ENV["RUBYMINE_HOME"]))
  end

  ENV["RAILS_ENV"] ||= 'test'
  require File.expand_path("../../config/environment", __FILE__)
  require 'rspec/rails'
  require 'rspec/autorun'

  Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}


  RSpec.configure do |config|
    config.use_transactional_fixtures = true
    config.infer_base_class_for_anonymous_controllers = false
    config.order = "random"
    config.include Capybara::DSL


    #Mongoid database cleaner
    config.before(:suite) do
      DatabaseCleaner[:mongoid, {:connection => :unit_test}].strategy = :truncation
      DatabaseCleaner[:mongoid, {:connection => :unit_test}].clean_with(:truncation)
    end

    config.before(:each) do
      DatabaseCleaner[:mongoid, {:connection => :unit_test}].start
    end

    config.after(:each) do
      DatabaseCleaner[:mongoid, {:connection => :unit_test}].clean
    end
  end
end

Spork.each_run do
  # This code will be run each time you run your specs.
  FactoryGirl.reload

end

Solution

  • Based on the path of the model, your FMStudent class should be defined as follows:

    # app/models/filemaker/fm_student.rb
    class Filemaker::FMStudent < FMBase
      def as_local_model
      end
      ...
    end
    

    Then you would call it as:

    /app/sync/file_maker_sync.rb
    class FileMakerSync
      def self.load_student(student_id)
        fm_student = Filemaker::FMStudent.find_single(student_id: student_id)
      end
      ...
    end