2017-02-17 233 views
0

我有一個模型domain.rbRSpec的測試失敗,NoMethodError

class Domain < ActiveRecord::Base 
    belongs_to :user 
    has_many :ranks, dependent: :destroy 

    validates_uniqueness_of :name, scope: :user_id, message: "You alredy entered that domain" 
    validates_presence_of :name 
    validate :user_quota, on: :create 

    def user_quota 
    errors.add(:base, 'OOps!!! You have Exceeded maximum domain limit/user (3)') if self.user.domains(:reload).count >= 3 
    end 
end 

在我domain_spec.rb我想測試自定義驗證 - 只能有3唯一的用戶

require 'rails_helper' 

RSpec.describe Domain, type: :model do 
    it " - cannot create a new domain if user already have 3 domains" do 

    user = User.create(name: "John Doe", email: '[email protected]', password: 'pw1234', 
    password_confirmation: 'pw1234') 

    user_domain1 = Domain.create(name: 'http://example1.com', user_id: user.id, 
       created_at: DateTime.now, updated_at: DateTime.now) 
    expect(user_domain1.errors).to be_empty 

    user_domain2 = Domain.create(name: 'http://example2.com', user_id: user.id, 
       created_at: DateTime.now, updated_at: DateTime.now) 
    expect(user_domain2.errors).to be_empty 

    user_domain3 = Domain.create(name: 'http://example3.com', user_id: user.id, 
       created_at: DateTime.now, updated_at: DateTime.now) 
    expect(user_domain3.errors).to be_empty 

    user_domain4 = Domain.create(name: 'http://example4.com', user_id: user.id, 
       created_at: DateTime.now, updated_at: DateTime.now) 
    expect(user_domain4.errors).to_not be_empty 

    end 
end 

運行我的測試時rspec spec/models/domain_spec.rb我得到錯誤:

Domain - cannot create a new domain if user already have 3 domains

Failure/Error: errors.add(:base, 'OOps!!! You have Exceeded maximum 
domain limit/user (3)') if self.user.domains(:reload).count >= 3 
NoMethodError: undefined method `domains' for nil:NilClass 

user.rb

class User < ActiveRecord::Base 
    has_many :domains 
    # Include default devise modules. Others available are: 
    # :confirmable, :lockable, :timeoutable and :omniauthable 
    devise :database_authenticatable, :registerable, 
     :recoverable, :rememberable, :trackable, :validatable, :confirmable, :lockable, :zxcvbnable 

    # Override Devise method to send mails in background 
    def send_devise_notification(notification, *args) 
    devise_mailer.send(notification, self, *args).deliver_later 
    end 
end 

我在做什麼錯?我是RSpec的新手,請幫我弄清楚這個問題。在此先感謝

+0

您是否已將'has_many:domains'添加到'User'模型中? – Uzbekjon

+0

@Uzbekjon是的,我有'has_many:domains'在user.rb –

+0

與你得到的錯誤沒有直接關係,但是':reload'應該在'self.user.domains(:reload).count '? –

回答

1

望着錯誤消息:

[...] self.user.domains(:reload).count >= 3 
    NoMethodError: undefined method `domains' for nil:NilClass 

這表明user未保存大概是因爲一些驗證錯誤(S)。現在的挑戰是找出爲什麼驗證失敗,所以你可以修復它。

在你的測試代碼,您正在創建這些數據庫條目如下:

user = User.create(name: "John Doe", ...) 
user_domain1 = Domain.create(name: 'http://example1.com', user_id: user.id, ...) 

一個簡單的方法來拿起什麼錯誤發生,讓你的測試失敗了更多有用的信息,是使用create! instead of create

user = User.create!(name: "John Doe", ...) 
user_domain1 = Domain.create!(name: 'http://example1.com', user_id: user.id, ...) 

這樣,一個RecordInvalid將引發異常,說明爲什麼該記錄不能保存的原因。

+1

爲了簡化測試,您可能希望使用的其他東西是通過工廠模式創建數據 - 例如,使用['factory_girl'](https://github.com/thoughtbot/factory_girl)(和'factory_girl_rails')。 –