Rails:确保after_create在rspec中运行

时间:2014-12-03 23:30:12

标签: ruby-on-rails ruby rspec

我遇到让Rspec运行我的after_create挂钩的问题。

我的用户模型:

class User < ActiveRecord::Base
  devise :database_authenticatable, :registerable, :recoverable, :rememberable,
         :trackable, :validatable, :confirmable

  has_one :user_profile

  after_create :create_user_profile

  protected

  def create_user_profile
    self.user_profile = UserProfile.new(user: self)
    self.user_profile.save
  end
end

我的UserProfile模型:

class UserProfile < ActiveRecord::Base
  belongs_to :user

  has_attached_file :avatar,
    styles: { medium: "300x300>", thumb: "100x100>" },
    default_url: "/images/:style/missing.png"
  validates_attachment :avatar,
    content_type: { content_type: "image/jpeg" }
end

我的规格:

require 'rails_helper'

RSpec.describe UserProfile, :type => :model do
  describe 'initial create' do
    before do
      @user = User.new(email: 'user@example.com',
                       password: 's3kr3t',
                       password_confirmation: 's3kr3t')
      @user.save
    end

    it 'should have profile' do
      expect(@user.user_profile).to be_valid
    end
  end
end

失败并显示错误:

Failures:                                                                                                                              │~
                                                                                                                                       │~
  1) UserProfile initial create should have profile                                                                                    │~
     Failure/Error: expect(@user.user_profile).to be_valid                                                                             │~
     NoMethodError:                                                                                                                    │~
       undefined method `valid?' for nil:NilClass                                                                                      │~
     # ./spec/models/user_profile_spec.rb:16:in `block (3 levels) in <top (required)>'                                                 │~

2 个答案:

答案 0 :(得分:1)

你可以这样做:

RSpec.describe UserProfile, :type => :model do
  describe 'initial create' do
    let(:user) { User.new(email: 'user@example.com',
                       password: 's3kr3t',
                       password_confirmation: 's3kr3t') }

    it 'should have profile' do
      @user.save
      expect(@user.user_profile).to_not be_nil
    end

    it "shouldn't have valid profile if not saved" do
      expect(@user.user_profile).to be_nil
    end
  end
end

答案 1 :(得分:0)

事实证明,给定的代码有多个错误,其中大部分与无效的用户模型有关:

  1. Devise希望密码最少为8个字符(因此我的用户模型由于无效而无法保存)。
  2. 我错过了添加3&#34;确认&#34;字段到用户模型迁移。
  3. 迁移我的用户模型后,我需要添加一个&#34; confirmed_at&#34;属于实例化的用户模型。
  4. 我的UserProfile模型也缺少&#34; user_id&#34;迁移中的属性。
  5. 解决了这些问题后,代码按预期工作。