0

In the Rails tutorial by Michael Hertl, I don't get what is the point of this? Is it just for double-checking that user meets the requirements?

The other code below does the validation so I don't see or understand the point of this:

require 'spec_helper'

describe User do 

  before do
    @user = User.new(name: "Example User", email: "user@example.come",
      password: "foobar", password_confirmation: "foobar")
  end

  subject { @user} 

  it { should respond_to(:name)  }
  it { should respond_to(:email) }
  it { should respond_to(:password_digest) }
  it { should respond_to(:password) }
  it { should respond_to(:password_confirmation) }
  it { should respond_to(:authenticate) }

  it {should be_valid }

  describe "when name is not present" do
    before { @user.name = " " }
    it { should_not be_valid }
  end

  describe "when email is not present" do
    before { @user.email = " " }
    it { should_not be_valid }
  end

  describe "when name is too long" do
    before { @user.name = "a" * 51 }
    it { should_not be_valid }
  end

  describe "when email format is invalid" do
    it "should be invalid" do
      addresses = %w[user@foo,com user_at_foo.org example.user@foo.
        foo@bar_baz.com foo@bar+baz.com]
        addresses.each do |invalid_address|
          @user.email = invalid_address
          expect(@user).not_to be_valid
        end
      end
    end
    describe "when email format is valid" do
      it "should be valid" do
        addresses = %w[user@foo.COM A_US-ER@f.b.org frst.lst@foo.jp a+b@baz.cn]
        addresses.each do |valid_address|
          @user.email = valid_address
          expect(@user).to be_valid
        end
      end
    end

    describe "when email addresses is already taken" do 
      before do
        user_with_same_email = @user.dup
        user_with_same_email.save
      end

      it { should_not be_valid }
    end

    describe "when password is not present" do
      before do
        @user = User.new(name: "Example User", email: "user@example.come",
          password: " ", password_confirmation: " ")
      end
      it { should_not be_valid }
    end

    describe "when password doesn't match confirmation" do
      before { @user.password_confirmation = "mismatch" }
      it { should_not be_valid }
    end

    describe "with a password that's too short" do
      before { @user.password = @user.password_confirmation = "a" * 5 }
      it { should be_invalid }
    end

    describe "return value of authenticate method" do
      before { @user.save }
      let(:found_user) { User.find_by(email: @user.email) }

      describe "with valid password" do
        it { should eq found_user.authenticate(@user.password) }
      end

      describe "with invalid password" do
        let(:user_for_invalid_password) { found_user.authenticate("invalid") }

        it { should_not eq user_for_invalid_password }
        specify { expect(user_for_invalid_password).to be_false }
      end
    end

  end

Compared to just using:

class User < ActiveRecord::Base
  before_save { self.email = email.downcase }
  validates :name, presence: true, length: { maximum: 50 }
  VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
  validates :email, presence: true, format: { with: VALID_EMAIL_REGEX },
  uniqueness: { case_sensitive: false }

  has_secure_password
  validates :password, length: { minimum: 6}
end
Simone Carletti
  • 173,507
  • 49
  • 363
  • 364
user3131148
  • 343
  • 1
  • 5
  • 18
  • See the answer to your other question - the code in the spec describes what your application is supposed to do and checks under different scenarios it works as described. The model code implements those rules; the spec confirms that what you implemented in the model matches what you intended to do. http://stackoverflow.com/questions/20928503/i-dont-understand-the-rails-validates-presence-from-tutorial – Steve Rowley Jan 05 '14 at 03:06

2 Answers2

2

Rspec is a way of testing your code. it is extremely useful as it allows you to check later whether the new batch of code you just wrote broke any functionality of the code. It is not required for code to work, but it is not possible to write a scalable and maintainable web application without those tests.

I would recommend you to read about TDD (test driven development). It will feel strange to do this at beginning, but you will notice that writing test actually makes your code better and cleaner.

BroiSatse
  • 44,031
  • 8
  • 61
  • 86
0

I think I know what you mean, I have gone through the Ruby on Rails Tutorial book as well. I was also a bit surprised about the amount of testing what is done, before writing a single line of actual code. Before I had studied the Ruby on Rails Tutorial book, I had only used Unit Testing in other projects; also RSpec was new to me. When I used Unit Testing, the Unit Tests weren't created until the program code was written; so I found this approach, Test-Driven Development, a bit strange, because I didn't have any actual code to test, although I had already created tests for it.

After getting more used to TDD, I have started to think that it's a very useful way of creating software, especially when quality is considered. I think it is practical to use TDD, if you start a software project from scratch, because those tests are something that you can rely on making sure that your code works. Also when you make changes to your code, you can use those tests verify that your old code works. But like Mikael Hartl says in the book: β€œIt's important to understand that TDD is not always the right tool for the job. There's no reason to dogmatically insist that tests always should be written first, that they should cover every single feature, or that there should necessarily be any tests at all. For example, when you aren't at all sure how to solve a given programming problem, it's often useful to skip the tests and write only application code, just to get a sense of what the solution will look like.”

jyrkim
  • 2,849
  • 1
  • 24
  • 33