ruby-on-railsvalidationrspectddvalidates-uniqueness-of

Testing the validation of uniqueness of the field in Rails's model using rspec without helper gems


I'm trying to write test to validate the uniqueness of the field in RoR's model.

I am working on Ruby on Rails apps which I use to practice my skills in TDD. I have used Internet as my resource so far. I'm writing testing on validation for model.I will not be using 'shoulda', 'FactoryGirl' (and etc) gems. I know using those gems will save me lots of coding but I will use those gems eventually. I want to learn how to write rspec test on it own without gems to help me understand how to write testing. I am doing good so far until 'uniqueness' testing.

How do I create test to validate the uniquenss of the 'email' field in 'User' model without using 'shoulda', 'FactoryGirl' (and etc) gems. I know using those gems will save lots of coding but I will use those gems eventually. I want to learn how to write rspec test on it own without gems to help me understand how to write testing.

Most 'answer' to this questions on Stackoverflow (and elsewhere on the Net) includes the use of those helper gems. But find no answer to this without gems.

Here is model, User.rb ```

class User < ApplicationRecord
  validate: :name, :email, presence: true
  validates :name, length: { minimum: 2 }
  validates :name, length: { maximum: 50 }
  # validates_format_of :email, with: /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i
  validates :email, format: { with: /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i, on: :create }
  validates :email, uniqueness: true
end

And here is `user_spec.rb`.

require 'rails_helper'

RSpec.describe User, type: :model do
  subject {
    described_class.new(name: 'John', email: 'john@home.xyz')
  }

  describe 'Validation' do
    it 'is valid with valid attributes' do
      expect(subject).to be_valid
    end

    it 'is not valid without name' do
      subject.name = nil
      expect(subject).to_not be_valid
    end

    it 'is not valid without email' do
      subject.email = nil
      expect(subject).to_not be_valid
    end

    (...)

    it 'is invalid if the email is not unique' do
      expect(????????).to_not be_valid
    end

  end
end

```

how do I write to test for uniqueness. Should I use something else other than 'subject' to test against? Remember, I don't want a solution that use gems (Shoulda/FactoryGirl/etc) this time.

I've been at it for the last few days and no luck. Any solution? And where is the best tutorial on rspec on Ruby on Rails?


Solution

  • To test for uniqueness, first you have to create a user with same email as used in subject. Then, your subject would be invalid because of uniqueness validation on email.

    Something like:

    before { described_class.create!(name: 'foo', email: 'john@home.xyz') }
    it 'is invalid if the email is not unique' do
      expect(subject).to be_invalid
    end