【发布时间】:2017-11-17 18:33:08
【问题描述】:
我无法理解 Rspec(rspec 3.7,rails 5.1.4)没有抛出与数据库约束相关的异常(如预期)的行为。
假设创建一个具有 not null 约束的表,如下所示:
create_table :ce_teams do |t|
t.string :name
t.integer :evaluation_id, null: false
t.timestamps
end
对应型号是这样的:
module Ce
class Team < ApplicationRecord
belongs_to :evaluation
end
end
然后在控制台内创建 Team 对象会引发 ActiveRecord::NotNullViolation 异常:
#\>RAILS_ENV=test rails c
Loading test environment (Rails 5.1.4)
2.4.2 :001 > t1 = Ce::Team.create(name: 'A-Team')
(0.2ms) BEGIN
SQL (1.2ms) INSERT INTO "ce_teams" ("name", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id" [["name", "A-Team"], ["created_at", "2017-11-17 18:13:17.444797"], ["updated_at", "2017-11-17 18:13:17.444797"]]
(0.2ms) ROLLBACK
ActiveRecord::NotNullViolation: PG::NotNullViolation: ERROR: null value in column "evaluation_id" violates not-null constraint
在 rspec 中运行相同的操作不是:
it 'throwing not null exception if evaluation is missing in ctor' do
expect {
Ce::Team.create(name: 'UTEAM')
}.to raise_exception(ActiveRecord::NotNullViolation)
end
测试失败,一方面由于 create 与 create! 的语义,这是预期的,但另一方面是意外的,因为不应该从模型验证中引发异常(在 create/创建!)但从保存记录的数据库中。
但是使用create! 会正确抛出异常,但它是一个不同的异常(我认为在堆栈中更高):
1) Ce::Team Team Model throwing not null exception if evaluation is missing in ctor
Failure/Error:
expect {
Ce::Team.create!(name: 'UTEAM')
}.to raise_exception(ActiveRecord::NotNullViolation)
expected ActiveRecord::NotNullViolation, got
#<ActiveRecord::RecordInvalid: Validation failed: Evaluation must exist>
发生了什么事?我的第一个直觉是 Rspec 中有一些层以不同的方式模拟创建(或保存),省略了实际的保存。
【问题讨论】:
标签: ruby-on-rails rspec ruby-on-rails-5.1 ruby-on-rails-5