Using TDD to Implement Data Validations in a Rails Application
In this guide, we are going to implement data validation for our models and we'll be using test driven development to integrate the feature.
Guide Tasks
  • Read Tutorial
  • Watch Guide Video
Video locked
This video is viewable to users with a Bottega Bootcamp license

In this guide, we are going to implement data validation for our models and we'll be using test driven development to integrate the feature. Let's start by creating some test cases.

Let's open our user_spec.rb located inside spec/models. First off, we are creating a code block called "Creation" to check if a user can be created. Typically, when you use the word describe in RSpec, it means you are creating a test case.

# spec/models/user_spec.rb

require 'rails_helper'

RSpec.describe User, type: :model do
  describe "Creation" do
    it "can be created" do
      user = User.create(email: "test@test.com", password: "asdfasdf", password_confirmation: "asdfasdf")
      expect(user).to be_valid
    end
  end
end

Now, if you open the console and run it with the command RSpec, the output will be:

large

Though the values are passing, it's not enough, since we need to require values such as first name and last name.

To do that, let's make some changes to our previous code. We'll create an instance variable called user in a before do block, so that the it "can be created" do block has access to it.

large

Rails will run the before do block first, so other parts of the code can use the variable user. If you run the code, the result will be the same as before, and that's good.

Next, let's say we make it mandatory to have the first name and last name of a user to create a record. We can test that with the following code:

# spec/models/user_spec.rb

it "cannot be created without first_name, last_name" do
  @user.first_name =  nil
  @user.first_name =  nil
  expect(@user).to_not be_valid
end

In this code, we are setting the first_name and last_name to nil, and we are not expecting this code to be valid. Let's also make a small change to our user record. Change it to:

@user = User.create(email:  "test@test.com", password: "asdfasdf", password_confirmation: "asdfasdf", first_name: "Jon", last_name: "Snow")

Let's run the code now. I'm going to make our RSpec run only the test cases in the model files, and the command for that is

rspec spec/models/

The output is:

large

If you see, there's a failure, and that's exactly what we want. The code did not expect first_name and last_name to be valid, but it was valid, and this threw up the error.

Now, let's put our validations in place. Go to user.rb, and include:

# app/models/user.rb

validates_presence_of :first_name, :last_name

Now, let's run our tests again. This time I'm going to be even more specific as I want to only run a particular test. So, it is:

rspec spec/models/user_spec.rb:13

Where 13 is the line number.

large

If you see it ran only one example, when compared to two examples of the previous run. And we're all green.

So, that's how you can implement validations in Rails using test-driven development.

In the next guide, we'll create our Post model.

Resources