Thibaud Clement
Thibaud Clement

Reputation: 6897

Rails validation test not passing

In our Rails app, we have the following models:

class User < ActiveRecord::Base
  has_many :administrations, dependent: :destroy
  has_many :calendars, through: :administrations
end

class Administration < ActiveRecord::Base
  belongs_to :user
  belongs_to :calendar
end

class Calendar < ActiveRecord::Base
  has_many :administrations, dependent: :destroy
  has_many :users, through: :administrations
end

We tried to validate the Administration model with the following administration_test.rb test file:

require 'test_helper'

class AdministrationTest < ActiveSupport::TestCase
  def setup
    @user = users(:noemie)
    @administration = Administration.new(user_id: @user.id, calendar_id: @calendar_id)
  end

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

  test "user id should be present" do
    @administration.user_id = nil
    assert_not @administration.valid?
  end

  test "calendar id should be present" do
    @administration.calendar_id = nil
    assert_not @administration.valid?
  end

end

When we run the test, we get the following results:

FAIL["test_calendar_id_should_be_present", AdministrationTest, 2015-06-30 07:24:58 -0700]
 test_calendar_id_should_be_present#AdministrationTest (1435674298.26s)
        Expected true to be nil or false
        test/models/administration_test.rb:21:in `block in <class:AdministrationTest>'

 FAIL["test_user_id_should_be_present", AdministrationTest, 2015-06-30 07:24:58 -0700]
 test_user_id_should_be_present#AdministrationTest (1435674298.27s)
        Expected true to be nil or false
        test/models/administration_test.rb:16:in `block in <class:AdministrationTest>'

We are kind of lost: is this the right way to right the test?

If no, how should we write it? If yes, how can we make it pass?

Upvotes: 0

Views: 429

Answers (2)

Thibaud Clement
Thibaud Clement

Reputation: 6897

Ok, we found the solution.

We updated our Administration model as follows:

class Administration < ActiveRecord::Base
  belongs_to :user
  belongs_to :calendar

  validates :user_id, presence: true
  validates :calendar_id, presence: true

end

And also edited our administration_test.rb file:

require 'test_helper'

class AdministrationTest < ActiveSupport::TestCase
  def setup
    @user = users(:noemie)
    @calendar = calendars(:one)
    # This code is not idiomatically correct.
    @administration = Administration.new(user_id: @user.id, calendar_id: @calendar.id)
  end

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

  test "user id should be present" do
    @administration.user_id = nil
    assert_not @administration.valid?
  end

  test "calendar id should be present" do
    @administration.calendar_id = nil
    assert_not @administration.valid?
  end

end

The tests are now passing just fine.

Upvotes: 0

max
max

Reputation: 102046

The problem is not your test but rather that you are expecting the wrong outcome.

belongs_toin ActiveRecord does not add a validation, the macro simply creates a relation.

To validate a relation you would use validates_associated which calls #valid? on each of the associated records and validates_presence_of to ensure that the associated record is present.

class Administration < ActiveRecord::Base
  belongs_to :user
  belongs_to :calendar
  validates_associated :user 
  validates :user, presence: true
end

When testing validations it is better to write on the assertions on the errors hash, as assert_not @administration.valid? will give a false positive if the validation fails for any other reason.

Bad:

test "user id should be present" do
  @administration.user_id = nil
  assert_not @administration.valid?
end

Good:

test "user id should be present" do
  @administration.user_id = nil
  @administration.valid?
  assert @administration.errors.key?(:user)
end

Upvotes: 1

Related Questions