RSpec 未通过 'should save' 测试
RSpec not passing 'should save' test
我是测试新手 Rails 所以这可能是一件非常小的事情,但我不知道哪里出了问题。所以我有一些我想测试的模型。现在测试很简单;测试属性的存在并在满足所有验证时保存。
我的一个模型 Profile
belongs_to
我的 Users
模型和 passes 所有这些测试 spec/models/profiles_spec.rb
:
require 'rails_helper'
RSpec.describe Profile, type: :model do
context 'validation tests' do
it 'ensures user_id presence' do
profile = Profile.new(platform: 0, region: 0, tag: 'GamerTag', sr: 1600).save
expect(profile).to eq(false)
end
it 'ensures platform presence' do
profile = Profile.new(user_id: 1, region: 0, tag: 'GamerTag', sr: 1600).save
expect(profile).to eq(false)
end
it 'ensures region presence' do
profile = Profile.new(user_id: 1, platform: 0, tag: 'GamerTag', sr: 1600).save
expect(profile).to eq(false)
end
it 'ensures tag presence' do
profile = Profile.new(user_id: 1, platform: 0, region: 0, sr: 1600).save
expect(profile).to eq(false)
end
it 'ensures sr presence' do
profile = Profile.new(user_id: 1, platform: 0, region: 0, tag: 'GamerTag').save
expect(profile).to eq(false)
end
it 'should save successfully' do
profile = Profile.new(user_id: 1, platform: 0, region: 0, tag: 'GamerTag', sr: 1600).save
expect(profile).to eq(true)
end
end
end
app/models/profile.rb
:
class Profile < ApplicationRecord
validates :platform, presence: true
validates :region, presence: true
validates :tag, presence: true
validates :sr, presence:true
belongs_to :user
enum platform: [:pc, :xbl, :psn]
enum region: [:us, :eu]
end
但是还有我的其他模型,其中 "pass" 所有属性存在验证测试,其中有一些错误,因为当我注释掉它们的属性验证并且未通过 'should save successfully'
时它们仍然通过测试。
最令人困惑的部分?当我 运行 rails 控制台并手动测试它时 returns 预期值 (true),就像我的 Student
模型 belongs_to :profile
.
所以我真的不知道这里发生了什么。任何想法请扔掉。如果大家需要更多信息,请告诉我。
首先,您正在以一种非常低效的方式编写测试。如果您不想测试验证,那么您不需要测试 save
方法 return 值,而是测试 valid?
方法的值和 errors
散列。
RSpec.describe Profile, type: :model do
context 'validation tests' do
it 'ensures user_id presence' do
profile = Profile.new(platform: 0, region: 0, tag: 'GamerTag', sr: 1600, user_id: nil) #you should be explicit with the user_id value being nil, tests should be explicit, it may seem unnecesary but it makes them easier to read
expect(profile).to be_invalid #or expect(profile).not_to be_valid
expect(profile.errors[:user_id]).to be_present #you could test the actual message too, not just the presence on any error
end
end
end
该测试实际上仅测试验证,并确保 user_id
字段中存在错误。
通过实际测试,您无法知道实际上是什么阻止了对象的保存。它可以是任何东西:另一个验证、before_save 回调 returning false、插入数据库时的无效值,任何东西。它也更慢,因为它必须实际将记录写入数据库,测试 valid?
是在内存上完成的,内存要快得多。
我建议您阅读有关 FactoryBot 的内容,这样您就不必在每次测试中重复 Profile.new....
。
如果你仍然想在上次测试中测试 save
的 return 值,你必须知道为什么它没有被保存,你可以使用 save!
这会引发一个异常而不是 returning false 来调试你的代码,你也可以检查 profile.errors.full_messages
看看是否有任何你在设置测试时没有考虑到的错误。
确实是缺少相关记录的错误。让我们以教练规格为例:
it 'should save successfully' do
coach = Coach.new(profile_id: 1, roles: ['tank']).save
expect(coach).to eq(true)
end
这里(在我的实验中)没有 id=1 的配置文件。事实上,根本没有配置文件。所以正如预期的那样,这个规范失败了。
Buuuut,当我们到达配置文件规范时:
it 'should save successfully' do
profile = Profile.new(user_id: 1, platform: 0, region: 0, tag: 'GamerTag', sr: 1600)
expect(profile).to eq(true)
end
ID=1 的用户 确实 存在(可能是因为用户规范在此之前是 运行 并成功创建了用户记录)。
要学习的课程:
- 始终 clean/rollback 测试之间的数据库(或以其他方式使其保持原始状态)
- 始终 运行 以随机顺序进行测试。正如您在此线程中看到的那样,规范顺序依赖性可能很难检测到。
我是测试新手 Rails 所以这可能是一件非常小的事情,但我不知道哪里出了问题。所以我有一些我想测试的模型。现在测试很简单;测试属性的存在并在满足所有验证时保存。
我的一个模型 Profile
belongs_to
我的 Users
模型和 passes 所有这些测试 spec/models/profiles_spec.rb
:
require 'rails_helper'
RSpec.describe Profile, type: :model do
context 'validation tests' do
it 'ensures user_id presence' do
profile = Profile.new(platform: 0, region: 0, tag: 'GamerTag', sr: 1600).save
expect(profile).to eq(false)
end
it 'ensures platform presence' do
profile = Profile.new(user_id: 1, region: 0, tag: 'GamerTag', sr: 1600).save
expect(profile).to eq(false)
end
it 'ensures region presence' do
profile = Profile.new(user_id: 1, platform: 0, tag: 'GamerTag', sr: 1600).save
expect(profile).to eq(false)
end
it 'ensures tag presence' do
profile = Profile.new(user_id: 1, platform: 0, region: 0, sr: 1600).save
expect(profile).to eq(false)
end
it 'ensures sr presence' do
profile = Profile.new(user_id: 1, platform: 0, region: 0, tag: 'GamerTag').save
expect(profile).to eq(false)
end
it 'should save successfully' do
profile = Profile.new(user_id: 1, platform: 0, region: 0, tag: 'GamerTag', sr: 1600).save
expect(profile).to eq(true)
end
end
end
app/models/profile.rb
:
class Profile < ApplicationRecord
validates :platform, presence: true
validates :region, presence: true
validates :tag, presence: true
validates :sr, presence:true
belongs_to :user
enum platform: [:pc, :xbl, :psn]
enum region: [:us, :eu]
end
但是还有我的其他模型,其中 "pass" 所有属性存在验证测试,其中有一些错误,因为当我注释掉它们的属性验证并且未通过 'should save successfully'
时它们仍然通过测试。
最令人困惑的部分?当我 运行 rails 控制台并手动测试它时 returns 预期值 (true),就像我的 Student
模型 belongs_to :profile
.
所以我真的不知道这里发生了什么。任何想法请扔掉。如果大家需要更多信息,请告诉我。
首先,您正在以一种非常低效的方式编写测试。如果您不想测试验证,那么您不需要测试 save
方法 return 值,而是测试 valid?
方法的值和 errors
散列。
RSpec.describe Profile, type: :model do
context 'validation tests' do
it 'ensures user_id presence' do
profile = Profile.new(platform: 0, region: 0, tag: 'GamerTag', sr: 1600, user_id: nil) #you should be explicit with the user_id value being nil, tests should be explicit, it may seem unnecesary but it makes them easier to read
expect(profile).to be_invalid #or expect(profile).not_to be_valid
expect(profile.errors[:user_id]).to be_present #you could test the actual message too, not just the presence on any error
end
end
end
该测试实际上仅测试验证,并确保 user_id
字段中存在错误。
通过实际测试,您无法知道实际上是什么阻止了对象的保存。它可以是任何东西:另一个验证、before_save 回调 returning false、插入数据库时的无效值,任何东西。它也更慢,因为它必须实际将记录写入数据库,测试 valid?
是在内存上完成的,内存要快得多。
我建议您阅读有关 FactoryBot 的内容,这样您就不必在每次测试中重复 Profile.new....
。
如果你仍然想在上次测试中测试 save
的 return 值,你必须知道为什么它没有被保存,你可以使用 save!
这会引发一个异常而不是 returning false 来调试你的代码,你也可以检查 profile.errors.full_messages
看看是否有任何你在设置测试时没有考虑到的错误。
确实是缺少相关记录的错误。让我们以教练规格为例:
it 'should save successfully' do
coach = Coach.new(profile_id: 1, roles: ['tank']).save
expect(coach).to eq(true)
end
这里(在我的实验中)没有 id=1 的配置文件。事实上,根本没有配置文件。所以正如预期的那样,这个规范失败了。
Buuuut,当我们到达配置文件规范时:
it 'should save successfully' do
profile = Profile.new(user_id: 1, platform: 0, region: 0, tag: 'GamerTag', sr: 1600)
expect(profile).to eq(true)
end
ID=1 的用户 确实 存在(可能是因为用户规范在此之前是 运行 并成功创建了用户记录)。
要学习的课程:
- 始终 clean/rollback 测试之间的数据库(或以其他方式使其保持原始状态)
- 始终 运行 以随机顺序进行测试。正如您在此线程中看到的那样,规范顺序依赖性可能很难检测到。