Search code examples
ruby-on-rails-4factory-botrspec-rails

Rpsec and Factory Girl not cooperating


I'm kind of pulling my hair out on this one. I'm trying to test using rspec and Factory Girl (Ubuntu 13.10 and Rails 4). It seems as if Rspec doesn't see any of the Factory Girl stuff. Here's my spec_helper.rb:

    # This file is copied to spec/ when you run 'rails generate rspec:install'
    ENV["RAILS_ENV"] ||= 'test'
     require File.expand_path("../../config/environment", __FILE__)
     require 'factory_girl_rails'
     require 'rspec/rails'
     require 'rspec/autorun'
     require 'capybara/rspec'

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

     ActiveRecord::Migration.check_pending! if defined?(ActiveRecord::Migration)

     RSpec.configure do |config|
       config.include FactoryGirl::Syntax::Methods

       config.use_transactional_fixtures = true

       config.infer_base_class_for_anonymous_controllers = false

       config.order = "random"
         config.color_enabled = true

         config.tty = true

         config.formatter = :documentation # :progress, :html, :textmate
     end

factories.rb:

    FactoryGirl.define do
      factory :exercise do
        name 'New Exercise'
        time 3
        reps 7
        weight 12
        weight_unit 'kg'
        factory :aerobic_exercise do
         name 'Jumping Jacks'
          kind 'Cardio/Aerobic'
        end
        factory :bodyweight_exercise do
          name 'Pushups'
          kind 'Bodyweight'
        end
        factory :cardio_exercise do
          name 'Jumping Jacks'
          kind 'Cardio/Aerobic'
        end
        factory :lifting_exercise do
          name 'BB Shoulder Presses'
          kind 'Weight Lifting'
        end
      end
    end

and my failing spec:

    #require 'test/spec'
    require 'spec_helper'

    describe Exercise do
      describe 'Exercise properly normalizes values' do
        it 'has weight and weight unit if kind is Weight Lifting' do
          let(:exercise) { FactoryGirl.create(:lifting_exercise) }
         exercise.should be_weight
          exercise.time.should be_nil
        end
        it 'has time but not weight etc. if kind is Cardio' do
          let(:exercise) { FactoryGirl.create(:aerobic_exercise) }
          exercise.should be_time
          exercise.reps.should be_nil
        end
      end
    end

When I run rspec I get this error:

         Failure/Error: let(:exercise) { FactoryGirl.create(:lifting_exercise) }
  NoMethodError:
    undefined method `let' for #    <RSpec::Core::ExampleGroup::Nested_1::Nested_1:0x007f2f013b3760>

HELP!(please)


Solution

  • the let method isn't from FactoryGirl, it's from Rspec, and the issue is that let should not be nested within the it, it's meant to be used outside of it.

    Given the way that you've written it, I think you should just use a local variable like this:

    describe Exercise do
      describe 'Exercise properly normalizes values' do
        it 'has weight and weight unit if kind is Weight Lifting' do
          exercise = FactoryGirl.create(:lifting_exercise)
          exercise.should be_weight
          exercise.time.should be_nil
        end
        it 'has time but not weight etc. if kind is Cardio' do
          exercise = FactoryGirl.create(:aerobic_exercise)
          exercise.should be_time
          exercise.reps.should be_nil
        end
      end
    end
    

    Also, given that you've included FactoryGirl::Syntax::Methods in your spec_helper you don't need to prefix everything with FactoryGirl, you can just call it like this:

    exercise = create(:lifting_exercise)

    I hope that helps!

    -Chad