Search code examples
ruby-on-railsrubyrailstutorial.org

Rails Tutorial: Undefined method errors in chapter 6


I'm currently working on 6.3.1 of Hartl's tutorial http://www.railstutorial.org/book/modeling_users

After running rails test I'm getting the following failures - I'm sure I'm misunderstanding the instructions or something. I'm grateful for any insight into what I'm doing wrong:

Error:
UserTest#test_should_be_valid:
NoMethodError: undefined method `valid?' for nil:NilClass
    test/models/user_test.rb:15:in `block in <class:UserTest>'

Error:
UserTest#test_email_should_be_present:
NoMethodError: undefined method `email=' for nil:NilClass
    test/models/user_test.rb:24:in `block in <class:UserTest>'

Error:
UserTest#test_email_addresses_should_be_saved_as_lower-case:
NoMethodError: undefined method `email=' for nil:NilClass
    test/models/user_test.rb:46:in `block in <class:UserTest>'

/test/models/user_test.rb

require 'test_helper'

class UserTest < ActiveSupport::TestCase

  def setup
    def setup
      @user = User.new(name: "Example User", email: "[email protected]",
                       password: "foobar", password_confirmation: "foobar")

    end

  end

  test "should be valid" do
    assert @user.valid?
  end

  test "name should be present" do
    @user.name = "a" * 51
    assert_not @user.valid?
  end

  test "email should be present" do
    @user.email = "a" * 244 + "@example.com"
    assert_not @user.valid?
  end

  test "email validation should accept valid adresses" do
    valid_adresses = %w[[email protected] [email protected] [email protected]
                        [email protected] [email protected]]
    valid_adresses.each do |valid_adresses|
      @user.email = valid_adresses
      assert @user.valid?, "#{valid_adresses.inspect} should be valid"
    end
  end

  test "email adresses should be unique" do
    duplicate_user = @user.dup
    duplicate_user.email = @user.email.upcase
    @user.save
    assert_not duplicate_user.valid?
  end

  test "email addresses should be saved as lower-case" do
    mixed_case_email = "[email protected]"
    @user.email = mixed_case_email
    @user.save
    assert_equal mixed_case_email.downcase, @user.reload.email
  end
end

/app/models/user.rb

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

end

Gemfile

source 'https://rubygems.org'

gem 'rails',        '5.0.2'
gem 'bcrypt-ruby', '~> 3.0.0'
gem 'bcrypt', git: 'https://github.com/codahale/bcrypt-ruby.git', :require => 'bcrypt'
gem 'puma',         '3.4.0'
gem 'sass-rails',   '5.0.6'
gem 'bootstrap-sass', '3.3.6'
gem 'uglifier',     '3.0.0'
gem 'coffee-rails', '4.2.1'
gem 'jquery-rails', '4.1.1'
gem 'turbolinks',   '5.0.1'
gem 'coffee-script-source', '1.8.0'
gem 'jbuilder',     '2.4.1'

group :development, :test do
  gem 'sqlite3', '1.3.12'
  gem 'byebug',  '9.0.0', platform: :mri
end

group :development do
  gem 'web-console',           '3.1.1'
  gem 'listen',                '3.0.8'
  gem 'spring',                '1.7.2'
  gem 'spring-watcher-listen', '2.0.0'
end

group :test do
  gem 'rails-controller-testing', '0.1.1'
  gem 'minitest-reporters',       '1.1.9'
  gem 'guard',                    '2.13.0'
  gem 'guard-minitest',           '2.4.4'
end

group :production do
  gem 'pg', '0.18.4'
end

# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]

Thanks so much in advance!


Solution

  • As per your post setup method you define wrongly

    1) you write def setup and inside of it again def setup

    2) Please check test database prepare properly.

    your code:

    def setup
      def setup
        @user = User.new(name: "Example User", email: "[email protected]",
                           password: "foobar", password_confirmation: "foobar")
        end   
    end
    

    Please try below

    require 'test_helper'
    
    class UserTest < ActiveSupport::TestCase
       setup do
         @user = User.new(name: "Example User", email: "[email protected]",
                          password: "foobar", password_confirmation: "foobar")
       end
    
       ...
     end