Logan Talbot
Logan Talbot

Reputation: 55

Rspec problems with model class named Spec, does not have expected model class methods

So I am getting this error every time I run a RSpec test for the model class Spec:

NoMethodError: undefined method `new' for Spec:Module
/home/log/.rvm/gems/ruby-2.3.1/gems/factory_girl-4.7.0/lib/factory_girl/decorator/new_constructor.rb:9:in `new'
/home/log/.rvm/gems/ruby-2.3.1/gems/factory_girl-4.7.0/lib/factory_girl/decorator.rb:14:in `send'
/home/log/.rvm/gems/ruby-2.3.1/gems/factory_girl-4.7.0/lib/factory_girl/decorator.rb:10:in `method_missing'
/home/log/.rvm/gems/ruby-2.3.1/gems/factory_girl-4.7.0/lib/factory_girl/decorator/invocation_tracker.rb:11:in `method_missing'
/home/log/.rvm/gems/ruby-2.3.1/gems/factory_girl-4.7.0/lib/factory_girl/decorator.rb:14:in `send'
/home/log/.rvm/gems/ruby-2.3.1/gems/factory_girl-4.7.0/lib/factory_girl/decorator.rb:10:in `method_missing'
/home/log/.rvm/gems/ruby-2.3.1/gems/factory_girl-4.7.0/lib/factory_girl/configuration.rb:19:in `block in initialize'
/home/log/.rvm/gems/ruby-2.3.1/gems/factory_girl-4.7.0/lib/factory_girl/attribute_assigner.rb:48:in `instance_exec'
/home/log/.rvm/gems/ruby-2.3.1/gems/factory_girl-4.7.0/lib/factory_girl/attribute_assigner.rb:48:in `build_class_instance'
/home/log/.rvm/gems/ruby-2.3.1/gems/factory_girl-4.7.0/lib/factory_girl/attribute_assigner.rb:13:in `object'
/home/log/.rvm/gems/ruby-2.3.1/gems/factory_girl-4.7.0/lib/factory_girl/evaluation.rb:12:in `object'
/home/log/.rvm/gems/ruby-2.3.1/gems/factory_girl-4.7.0/lib/factory_girl/strategy/build.rb:9:in `result'
/home/log/.rvm/gems/ruby-2.3.1/gems/factory_girl-4.7.0/lib/factory_girl/factory.rb:42:in `run'
/home/log/.rvm/gems/ruby-2.3.1/gems/factory_girl-4.7.0/lib/factory_girl/factory_runner.rb:29:in `block in run'
/home/log/.rvm/gems/ruby-2.3.1/gems/factory_girl-4.7.0/lib/factory_girl/factory_runner.rb:28:in `run'
/home/log/.rvm/gems/ruby-2.3.1/gems/factory_girl-4.7.0/lib/factory_girl/strategy_syntax_method_registrar.rb:20:in `block in define_singular_strategy_method'
./spec/models/spec_spec.rb:13:in `block (3 levels) in <top (required)>'
./spec/models/spec_spec.rb:16:in `block (3 levels) in <top (required)>'
-e:1:in `load'
-e:1:in `<main>'

I have looked to see if there was any of the expected model methods on the spec model class and none could be found.

Can I have 'spec' as a model name, if I am using RSpec or is there a was to work around it?

spec.rb (Rails Model)

class Spec < ApplicationRecord
  belongs_to :scenario

  validates :scenario_id, presence: true
  validates :description, presence: true,  length: { minimum: 1, maximum: 100 }
  validates :selected_section, presence: true, length: { maximum: 200 }
  validates :selected_action, presence: true, length: { maximum: 200 }
end

spec_spec.rb

 require 'rails_helper'

    RSpec.describe Spec, type: :model do
      context 'Relationship' do
        it 'should belong to project' do
          should belong_to(:scenario)
        end
      end

      context 'Validations' do
        let(:f) {FactoryGirl.build(:scenario)}
        subject do
          FactoryGirl.build(:spec, scenario: f)
        end
        it 'Correct input to be valid' do
          expect(subject).to be_valid
        end
        context 'scenario_id, needs to be' do
          it 'presence' do
            should validate_presence_of(:feature_id)
          end
        end
        context 'description, needs to be' do
          it 'presence' do
            should validate_presence_of(:description)
          end
          it 'minimum length of 1' do
            should validate_length_of(:description).is_at_least(1)
          end
          it 'maximum length of 100' do
            should validate_length_of(:description).is_at_most(100)
          end
        end
        context 'selected_section, needs to be' do
          it 'presence' do
            should validate_presence_of(:selected_section)
          end
          it 'maximum length of 100' do
            should validate_length_of(:selected_section).is_at_most(200)
          end
        end
        context 'selected_action, needs to be' do
          it 'presence' do
            should validate_presence_of(:selected_action)
          end
          it 'maximum length of 100' do
            should validate_length_of(:selected_action).is_at_most(200)
          end
        end
      end
    end

Upvotes: 0

Views: 62

Answers (1)

Midwire
Midwire

Reputation: 1100

As you already guessed, you are seeing a namespace clash between your Spec class and RSpec's Spec module.

Here are 2 ways to resolve it.

  1. Rename your class and its filename to Rails.root/models/the_spec.rb

    class TheSpec < ApplicationRecord
      belongs_to :scenario
    
      # ... your code
    end
    
  2. Namespace your class and move it to Rails.root/models/internal/spec.rb

    class Internal::Spec < ApplicationRecord
      belongs_to :scenario
    
      # ... your code
    end
    

You will also want to edit and move/rename your spec_spec.rb file to match as well.

Upvotes: 2

Related Questions