Tony Vincent
Tony Vincent

Reputation: 14362

RSpec test fails with NoMethodError

I have a model domain.rb

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

In my domain_spec.rb I am trying to test the custom validation - There can be only 3 domains for a unique user

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

when running my test rspec spec/models/domain_spec.rb I am getting error:

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

my 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

What am I doing wrong? I am new to RSpec, please do help me figure out this issue. thanks in advance

Upvotes: 0

Views: 790

Answers (1)

Tom Lord
Tom Lord

Reputation: 28305

Looking at the error message:

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

This indicates that the user was not saved, presumably because of some validation error(s). The challenge now is to find out why the validation is failing, so you can fix it.

In your test code, you are creating these database entries as follows:

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

A simple way to pick up on what error is occurring, so that your test fails with a more helpful message, is to use create! instead of create:

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

By doing this, an RecordInvalid exception will be raised, stating the reason why the record could not be saved.

Upvotes: 1

Related Questions