为什么未在 rails rspec 模型规范中设置主题的此属性?
Why is this attibute on a subject not being set in a rails rspec model spec?
我有一个测试模型的规范,如下所示:
RSpec.describe SomeModel, type: :model do
subject { described_class.new(test_amount: 99) }
describe 'validates a column' do
it 'does some validations' do
expect(subject).to validate_presence_of(:test_amount)
end
end
end
还有一个看起来像这样的模型:
class SomeModel < ApplicationRecord
validates :test_amount, presence: true
end
在模式中,它的列看起来像这样,带有一个非空集:
t.integer "test_amount", default: 0, null: false
无论我做什么或将代码放在哪里,test_amount 在测试和错误时始终为 nil。
我试过移动测试线,将主题放在之前等等,但总是
数据库抛出非空错误,即使我在模型代码中提出
test_amount 值不是 99,而是 nil。如果我提高测试值
之前是这样的:
before do
raise subject.test_amount
end
这确实会导致 99,但是如果我删除它,它始终为 nil 并在它到达测试的预期部分时抛出错误。
为了使该测试正常运行,我缺少什么,在实际测试步骤中进行测试时,我似乎无法将 test_amount
设置为 99。
测试总是抛出错误:
PG::NotNullViolation: ERROR: null value in column "test_amount" of relation "some_models" violates not-null constraint
或类似的,但我在验证前检查了 test_amount
的值,但没有设置。
感谢您的帮助,我觉得这里缺少一些非常基本的东西。
您可以使用如下 valid? and errors 方法为 presence
验证编写测试用例:
RSpec.describe SomeModel, type: :model do
subject { described_class.new(test_amount: test_amount) }
describe 'validates a column' do
context 'when valid test_amount'
let(:test_amount) { 99 }
it 'does not throw error' do
expect(subject.valid?).to eq(true)
expect(subject.errors[:test_amount].size).to eq(0)
end
end
context 'when invalid test_amount'
let(:test_amount) { nil }
it 'throws error' do
expect(subject.valid?).to eq(false)
expect(subject.errors[:test_amount].size).to eq(1)
end
end
end
end
这是否有可能是因为未在测试环境中 运行 迁移?
bundle exec rake db:prepare RAILS_ENV=test
# or for rack applications
bundle exec rake db:prepare RACK_ENV=test
除此之外,我认为是因为我们没有将记录保存到数据库中。我们不希望验证是 运行.
根据 this documentation,我们只希望在调用 Record#save
或 Record#save!
时进行 运行 验证。
当 运行 宁 Record#new
我们正在创建一个新实例但 没有保存 到我们的数据库。
Using the new method, an object can be instantiated without being saved:
当运行宁Record#create
我们初始化记录然后通过调用Record#save
.
将其保存到数据库
首先验证-
- 记录已保存。
- 一旦持久化,然后检查属性值。
此外,尝试将此行移动到 describe
块内 -
subject { described_class.new(test_amount: 99) }
我有一个测试模型的规范,如下所示:
RSpec.describe SomeModel, type: :model do
subject { described_class.new(test_amount: 99) }
describe 'validates a column' do
it 'does some validations' do
expect(subject).to validate_presence_of(:test_amount)
end
end
end
还有一个看起来像这样的模型:
class SomeModel < ApplicationRecord
validates :test_amount, presence: true
end
在模式中,它的列看起来像这样,带有一个非空集:
t.integer "test_amount", default: 0, null: false
无论我做什么或将代码放在哪里,test_amount 在测试和错误时始终为 nil。 我试过移动测试线,将主题放在之前等等,但总是 数据库抛出非空错误,即使我在模型代码中提出 test_amount 值不是 99,而是 nil。如果我提高测试值 之前是这样的:
before do
raise subject.test_amount
end
这确实会导致 99,但是如果我删除它,它始终为 nil 并在它到达测试的预期部分时抛出错误。
为了使该测试正常运行,我缺少什么,在实际测试步骤中进行测试时,我似乎无法将 test_amount
设置为 99。
测试总是抛出错误:
PG::NotNullViolation: ERROR: null value in column "test_amount" of relation "some_models" violates not-null constraint
或类似的,但我在验证前检查了 test_amount
的值,但没有设置。
感谢您的帮助,我觉得这里缺少一些非常基本的东西。
您可以使用如下 valid? and errors 方法为 presence
验证编写测试用例:
RSpec.describe SomeModel, type: :model do
subject { described_class.new(test_amount: test_amount) }
describe 'validates a column' do
context 'when valid test_amount'
let(:test_amount) { 99 }
it 'does not throw error' do
expect(subject.valid?).to eq(true)
expect(subject.errors[:test_amount].size).to eq(0)
end
end
context 'when invalid test_amount'
let(:test_amount) { nil }
it 'throws error' do
expect(subject.valid?).to eq(false)
expect(subject.errors[:test_amount].size).to eq(1)
end
end
end
end
这是否有可能是因为未在测试环境中 运行 迁移?
bundle exec rake db:prepare RAILS_ENV=test
# or for rack applications
bundle exec rake db:prepare RACK_ENV=test
除此之外,我认为是因为我们没有将记录保存到数据库中。我们不希望验证是 运行.
根据 this documentation,我们只希望在调用 Record#save
或 Record#save!
时进行 运行 验证。
当 运行 宁 Record#new
我们正在创建一个新实例但 没有保存 到我们的数据库。
Using the new method, an object can be instantiated without being saved:
当运行宁Record#create
我们初始化记录然后通过调用Record#save
.
首先验证-
- 记录已保存。
- 一旦持久化,然后检查属性值。
此外,尝试将此行移动到 describe
块内 -
subject { described_class.new(test_amount: 99) }