Merey Nurlan
Merey Nurlan

Reputation: 305

Passes validation even though column is nil Rspec

Rspec

it "should lastname" do
        valid_params[:lastname]     = nil
        user                        = User.new(valid_params)

        expect(user).to_not be_valid
end

it "should have username" do
        valid_params[:username]     = nil
        user                        = User.new(valid_params)

        expect(user).to_not be_valid
end

Migration file

create_table :users do |t|
      ## Database authenticatable
      t.string :email,              null: false, default: ""
      t.string :encrypted_password, null: false, default: ""
      t.string :firstname,          null: false, default: ""
      t.string :lastname,           null: false, default: ""
      t.string :username,           null: false, default: ""
      t.boolean :admin,             default: false

Model I do not have any validations except Devise validations

class User < ApplicationRecord
    after_initialize :set_initial_password
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
  devise :database_authenticatable, :registerable,
  :recoverable, :rememberable, :validatable

  private
  def set_initial_password
    if !self.firstname.nil? && !self.lastname.nil?
        self.password = self.firstname.downcase + self.lastname.downcase
    end
  end
end

Error

  1) User should have username
     Failure/Error: expect(user).to_not be_valid
       expected #<User id: nil, email: "[email protected]", firstname: "Garfield", lastname: "Koepp", username: nil, admin: false, created_at: nil, updated_at: nil> not to be valid

Rspec test does pass for lastname but not for username eventhough they have same conditions.

Upvotes: 2

Views: 748

Answers (1)

jamesc
jamesc

Reputation: 12837

For a validation to fail first you must have a validation so your model needs the following

validates :username, presence: true

Models do not validate against the database. They will validate against validation methods in the model. Without the validation your model will be valid but the database will reject it if you have not null restrictions in the DB

UPDATE response to comments

What you think is happening is not what is actually happening. There is only one reason why lastname test is passing and that is because user object is invalid. As you have not posted the full test only you can determine why the user object is failing validation in this case.

To find out what the errors are you should inspect the objects errors. Try the following code (untested but should work fine) and look at the console output for a list of invalid attributes

it "should lastname" do
        valid_params[:lastname]     = nil
        user                        = User.new(valid_params)
        user.errors.each do |error|
          puts("Err: #{error.inspect}")
        end 
        expect(user).to_not be_valid
end

Then you will understand what exactly is failing. If lastname is actually failing you will see the reason as blank or invalid for lastname. if lastname does not appear in the output then it is not in error. Should you see lastname in the error list then there is a validation on lastname in devise. I am not at all familiar with devise as I always roll my own authentication logic so perhaps this is something to do with one of the options you have included.

I can not say this clearly enough. If there is no validation code then it is not possible for a model instance to be invalid.

Upvotes: 3

Related Questions