I am having site where users can create products upon signup and products can have checklists.
I am having a checklist table with following columns:-
id | product_id | content | archived
I am new to rails testing. I wrote the test below
test 'should have content' do
checklist = Checklist.new
assert checklist.save
end
and run the test with following command
ruby -I test test/models/checklist_test.rb
and test is failed with Expected false to be truthy error.
Is it because of the problem a checklist can be accessed using user.product.checklists i have to populate the data in fixtures first and call those in testing?
EDIT 1
I don't have any validations in checklist model.
class Checklist < ApplicationRecord belongs_to :product end
I added ! in test save like below
test 'should have content' do
checklist = Checklist.new
assert checklist.save!
end
and got this error
ActiveRecord::RecordInvalid: Validation failed: Product must exist
cause the table has product_id in it. I don't know how to supply data to rails test. Any help?
EDIT 2
The error is eliminated after editing like below.
class Checklist < ApplicationRecord belongs_to :product, optional: true end
However i want to test the model with product
present. I don't know how to supply data to the test with fixtures as if there is no foreign key i can use Checklist.new
in test.
Since it has foreign key how can i supply data to Checklist
as it belongs to Product
which itself belongs to User
?
checklist.save
will return false
if the checklist
failed to save for some reason; presumably because a validation failed .
For example, perhaps your app/models/checklists.rb
contains something like:
validates :product_id, presence: true
Or:
validates :content, length: { minimum: 10 }
Etc. In this simple scenario, you can probably easily determine the error by just looking at the model definition; but for a more complex application you could view: checklist.errors.messages
to see a list of reasons why the record failed to save.
Judging by the test name ( "should have content" ), my guess is that it's failing because content
cannot be blank!
To make this test pass, for example, perhaps you need to write:
test 'should have content' do
checklist = Checklist.new(content: 'hello world')
assert checklist.save
end
One common approach that people use when testing this sort of thing is to define a "valid record" in factories ; this lets you explicitly test for invalid records, rather than having to explicitly re-define valid records in lots of place. For example, here you could do:
# test/factories/checklists.rb
FactoryBot.define do
factory :checklist do
content 'test content'
end
end
# test/models/checklist_test.rb
test 'should have content' do
checklist = build(:checklist, content: nil)
refute checklist.save # Expecting this to FAIL!
assert_includes "Content cannot be nil", checklist.errors
end
(Code may not be 100% complete/accurate; but you get the idea)
I have learned Fixtures to solve this problem.
Fixtures are designed in a way that even associated data(association in model) can be done. For example in my test i have written
checklist = checklists(:one)
to get a test data for checklist. In checklists fixtures(checklists.yml)
one:
product: one
content: Entry
hashtag: '#markets'
archived: false
done: false
where
product: one
refers to :one data in products.yml which is
one:
user: one
name: Test
role: Will decide
and thus association in fixtures is done.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.