Rspec测试没有传递Michael Hartl的教程10.1.4节

时间:2012-07-11 01:22:39

标签: ruby-on-rails ruby factory-bot railstutorial.org spork

我是RoR的完整新手,我正在研究Hartl rails教程(http://ruby.railstutorial.org/)。我坚持第10.1.4节的测试我继续得到以下错误:

故障:

1)用户微博关联应该破坏相关的微博      失败/错误:FactoryGirl.create(:micropost,用户:@user,created_at:1.day.ago)      NoMethodError:        '

中未定义的方法content=' for #<User:0x007fce7c86b1e8> # ./spec/models/user_spec.rb:147:in阻止(3个级别)

2)用户微博协会应该以正确的顺序拥有正确的微博      失败/错误:FactoryGirl.create(:micropost,用户:@user,created_at:1.day.ago)      NoMethodError:        '

中未定义的方法content=' for #<User:0x007fce7cbd6288> # ./spec/models/user_spec.rb:147:in阻止(3个级别)

由于我是一个新手,我的调试功能相当有限。我相信这不是一个大问题,所以我很感激我能得到的任何帮助,这是我的代码:

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: "user@example.com",
                         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

最后我的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

感谢您对我的任何帮助。

2 个答案:

答案 0 :(得分:3)

由于您已将:micropost工厂添加到section 10.1.4中的 spec / factories.rb ,因此您重新启动Spork后将反映您对该文件的添加。

答案 1 :(得分:0)

您的USER_SPEC.RB似乎缺少

it { should respond_to(:remember_token) } 

Mine看起来像这样,它可以工作,测试通过

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) }