Reputation: 6897
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
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
Reputation: 102046
The problem is not your test but rather that you are expecting the wrong outcome.
belongs_to
in 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