0
votes

I am a complete newby at RoR and I am working through the Hartl rails tutorial (http://ruby.railstutorial.org/). I am stuck on the tests for section 10.1.4 I keep on getting the following errors:

Failures:

1) User micropost associations should destroy associated microposts Failure/Error: FactoryGirl.create(:micropost, user: @user, created_at: 1.day.ago) NoMethodError: undefined method content=' for #<User:0x007fce7c86b1e8> # ./spec/models/user_spec.rb:147:inblock (3 levels) in '

2) User micropost associations should have the right microposts in the right order Failure/Error: FactoryGirl.create(:micropost, user: @user, created_at: 1.day.ago) NoMethodError: undefined method content=' for #<User:0x007fce7cbd6288> # ./spec/models/user_spec.rb:147:inblock (3 levels) in '

Since I am such a newbie my debugging capabilities are rather limited. I am sure this is not a huge issue so I would appreciate any help that I can get, here is the code I have:

USER_SPEC.RB

    require 'spec_helper'

    describe User do

      # Before means this code will run before every test is performed  
      before do
        @user = User.new(name: "Example User", email: "[email protected]",
                         password: "foobar", password_confirmation: "foobar")
      end

      subject { @user }

      it { should respond_to(:admin) }
      it { should respond_to(:authenticate) }
      it { should respond_to(:name) }
      it { should respond_to(:email) }
      it { should respond_to(:password_digest) }
      it { should respond_to(:password) }
      it { should respond_to(:password_confirmation) }
      it { should respond_to(:microposts) } 

      it { should be_valid }
      it { should_not be_admin }

      .
      .
      .
      .

      describe "micropost associations" do

        before { @user.save }
        let!(:older_micropost) do
          FactoryGirl.create(:micropost, user: @user, created_at: 1.day.ago)
        end
        let!(:newer_micropost) do
          FactoryGirl.create(:micropost, user: @user, created_at: 1.hour.ago)
        end

        it "should destroy associated microposts" do
          microposts = @user.microposts
          @user.destroy
          microposts.each do |micropost|
            Micropost.find_by_id(micropost.id).should be_nil
          end
        end

        it "should have the right microposts in the right order" do
          @user.microposts.should == [newer_micropost, older_micropost]
        end
      end
    end

USER.RB

    class User < ActiveRecord::Base
      attr_accessible :name, :email, :password, :password_confirmation
      has_secure_password
      has_many :microposts, dependent: :destroy

      before_save { self.email.downcase! }
      before_save :create_remember_token

      validates :name, presence: true, length: { maximum: 50 }

      VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
      validates :email, presence: true, format: { with: VALID_EMAIL_REGEX },
                uniqueness: { case_sensitive: false }

      validates :password, presence: true, length: { minimum: 6 }
      validates :password_confirmation, presence: true

      private

        def create_remember_token
          self.remember_token = SecureRandom.urlsafe_base64
        end

    end

MICROPOST_SPEC.RB

    require 'spec_helper'

    describe Micropost do

      let(:user) { FactoryGirl.create(:user) }
      before { @micropost = user.microposts.build(content: "Lorem ipsum") }

      subject { @micropost }

      it { should respond_to(:content) }
      it { should respond_to(:user_id) }
      it { should respond_to(:user) }
      its(:user) { should == user }

      it { should be_valid }

      describe "when user_id is not present" do
        before { @micropost.user_id = nil }
        it { should_not be_valid }
      end

      describe "accessible attributes" do
        it "should not allow access to user_id" do
          expect do
            Micropost.new(user_id: user.id)
          end.should raise_error(ActiveModel::MassAssignmentSecurity::Error)
        end    
      end
    end

MICROPOST.RB

    class Micropost < ActiveRecord::Base
      attr_accessible :content
      belongs_to :user

      validates :user_id, presence: true
      default_scope order: 'microposts.created_at DESC'
    end

FACTORIES.RB

    FactoryGirl.define do
      factory :user do
        sequence(:name)  { |n| "Person #{n}" }
        sequence(:email) { |n| "person_#{n}@example.com"}   
        password "foobar"
        password_confirmation "foobar"

        factory :admin do
          admin true
        end
      end

      factory :micropost do
        content "Lorem ipsum"
        user
      end
    end

AND LASTLY MY GEMFILE:

    source 'https://rubygems.org'

    gem 'rails', '3.2.5'
    gem 'jquery-rails', '2.0.0'
    gem 'bootstrap-sass', '2.0.0'
    gem 'bcrypt-ruby', '3.0.1'
    gem 'faker', '1.0.1'
    gem 'will_paginate', '3.0.3'
    gem 'bootstrap-will_paginate', '0.0.6'
    gem 'hirb'

    group :development, :test do
      gem 'sqlite3', '1.3.5'
      gem 'rspec-rails', '2.10.0'
      gem 'guard-rspec', '0.5.5'
    end

    # Gems used only for assets and not required
    # in production environments by default.
    group :assets do
      gem 'sass-rails',   '3.2.4'
      gem 'coffee-rails', '3.2.2'
      gem 'uglifier', '1.2.3'
    end

    group :test do
      gem 'capybara', '1.1.2'
      gem 'factory_girl_rails', '1.4.0'
      gem 'cucumber-rails', '1.2.1', :require => false
      gem 'database_cleaner', '0.7.0'
      gem 'guard-spork', '0.3.2'  
      gem 'spork', '0.9.0'
      gem 'launchy', '2.1.0'
      gem 'rb-fsevent', '0.9.1', :require => false
      gem 'growl', '1.0.3'
    end

    group :production do
      gem 'pg', '0.12.2'
    end

Thank you for any help I an get on this.

2
Your code seems to be okay, but since you added the :micropost factory to spec/factories.rb in section 10.1.4, you may need to restart your server (or spork since I assume you're using it) for those changes to be reflected.Paul Fioravanti
Thank you very much Paul. You were right. A restart of the server was exactly what I needed. I was using guard-spork. I tried restarting guard-spork but that didn't work, then once I read your suggestion, I restarted the server and all the tests are passing now.felipeab
Great! I'll put that in as the answer so this question can be closed.Paul Fioravanti

2 Answers

3
votes

Since you added the :micropost factory to spec/factories.rb in section 10.1.4, your additions to that file will be reflected once you restart Spork.

0
votes

It seems like in your USER_SPEC.RB you are missing

it { should respond_to(:remember_token) } 

Mine looks like this and it works, the tests pass

subject { @user }
it { should respond_to(:admin) }
it { should respond_to(:authenticate) }
it { should respond_to(:name) }
it { should respond_to(:email) }
it { should respond_to(:password_digest) }
it { should respond_to(:password) }
it { should respond_to(:password_confirmation) }
it { should respond_to(:remember_token) }
it { should respond_to(:microposts) }