Integrating Data Validations with RSpec Tests
In this guide we'll walk through how to implement data validations establish default values using Test Drive Development practices.
Guide Tasks
  • Read Tutorial
  • Watch Guide Video
Video locked
This video is viewable to users with a Bottega Bootcamp license

Now that we have our FactoryGirl code in place for audit logs, let's add in some data validations.

Open the audit_log_spec.rb file and add our first test case to check if the audit log can be created.

# spec/models/audit_log_spec.rb

require 'rails_helper'

RSpec.describe AuditLog, type: :model do
  before do
    @audit_log = FactoryGirl.create(:audit_log)
  end

  describe 'creation' do
    it 'can be properly created' do
      expect(@audit_log).to be_valid
    end
  end
end

If you run rspec, everything is green, and this is expected since our system already allows for creating audit logs. Usually I like to implement these type of base case scenarios to ensure that the tests are wired up properly. Next, let's implement some validations. Before we create the validations, let's list them out.

  • Audit log should be associated with the user.
  • Status is a required field
  • Start date is required
  • Start date should be equal to six days prior

The first three validations should be fairly straightforward.

The code for the first test is:

# spec/models/audit_log_spec.rb

describe 'validations' do
  it 'it should be required to have a user association' do
    @audit_log.user_id = nil
    expect(@audit_log).to_not be_valid
  end
end

As expected rspec throws an error. Let's create the same tests for the status and start_date since the implementation for them is going to be the same.

# spec/models/audit_log_spec.rb

it 'it should always have a status' do
  @audit_log.status = nil
  expect(@audit_log).to_not be_valid
end

it 'it should be required to have a start_date' do
  @audit_log.start_date = nil
  expect(@audit_log).to_not be_valid
end

To fix these errors, open the audit_log.rb model file and include this code:

# app/models/audit_log.rb

validates_presence_of :user_id, :status, :start_date

Now, rspec clears all these test failures for us.

Let's go to the last, and probably the most complex test. This test will confirm that the start date is six days prior. As a first step, let's create an audit log and store it in a local variable called new_audit_log. Then, we are going to check if the start date is six days earlier. The code for that should be:

# spec/models/audit_log_spec.rb

it 'it should have a start date equal to 6 days prior' do
  new_audit_log = AuditLog.create(user_id: User.last.id)
  expect(new_audit_log.start_date).to eq(Date.today - 6.days)
end 

Run rspec, and we get the error we want. So, open audit_log.rb and do a callback for a private method called set_defaults. In this private method, our code should check if there is already a start date, and if there isn't one, it will add a date that is six days before today. Code for this functionality should look like this:

# app/models/audit_log.rb

class AuditLog < ActiveRecord::Base
  belongs_to :user
  validates_presence_of :user_id, :status, :start_date
  after_initialize :set_defaults


  private

    def set_defaults
      self.start_date ||= Date.today - 6.days
    end
end

If you run rspec, everything works fine. Now, open the rails console in sandbox mode, and create an audit log with just the user id. It creates a record without any error even though status and start_date are required values. This is because the defaults are set by the code, and this is just what we want.

Resources