我无法理解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!)但是从数据库保存记录。
然而,使用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中存在一些以不同方式模拟创建(或保存)的层,省略了实际的保存。
答案 0 :(得分:1)
我无法重现这个问题。这是我得到的输出
$ RAILS_ENV=development bin/rails c
Running via Spring preloader in process 24202
Loading development environment (Rails 5.1.4)
2.4.0 :001 > team = Team.create(name: 'A-Team')
(0.3ms) BEGIN
(0.3ms) ROLLBACK
=> #<Team id: nil, name: "A-Team", created_at: nil, updated_at: nil, evaluations_id: nil>
2.4.0 :002 > team.errors.full_messages
=> ["Evaluation must exist"]
2.4.0 :003 > team = Team.create!(name: 'A-Team')
(0.5ms) BEGIN
(0.5ms) ROLLBACK
ActiveRecord::RecordInvalid: Validation failed: Evaluation must exist
from (irb):3
正如您所看到的,错误与create
和create!
相同。尝试使用bin/rails
而不是rails
,我怀疑您使用的是2个不同版本的Rails。