2017-02-17 265 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')。 –