我正在使用rails 5.0.2,ruby 2.4.0和postgresql 9.6.2编写博客应用程序。我使用Rspec编写了一些测试来检查postgres检查约束是否阻止将无效数据保存到数据库中。 null约束在Rspec中传递,但长度检查约束失败。但是,当我尝试在rails控制台中保存相同的数据时,我会收到错误。
我使用Rspec编写了以下测试数据库检查:
require 'rails_helper'
RSpec.describe User, type: :model do
describe 'database checks' do
context 'without email' do
let :user { build :user, email: nil }
it { expect {user.save validate: false}.to raise_error ActiveRecord::StatementInvalid }
end
context 'without name' do
let :user { build :user, name: nil }
it { expect {user.save validate: false}.to raise_error ActiveRecord::StatementInvalid}
end
context 'without encrypted password' do
let :user { build :user, encrypted_password: nil }
it { expect {user.save validate: false}.to raise_error ActiveRecord::StatementInvalid }
end
context 'empty email' do
let :user { build :user, email: '' }
it { expect {user.save validate: false}.to raise_error ActiveRecord::StatementInvalid }
end
context 'empty name' do
let :user { build :user, name: ''}
it { expect {user.save validate: false}.to raise_error ActiveRecord::StatementInvalid }
end
end
end
用户工厂:
FactoryGirl.define do
factory :user, do
email "test@example.com"
password "test password"
name "Test"
created_at { 5.seconds.ago }
updated_at { DateTime.now }
description "Test description
end
end
用户表:
CREATE TABLE users (
id integer NOT NULL,
email character varying DEFAULT ''::character varying NOT NULL,
encrypted_password character varying DEFAULT ''::character varying NOT NULL,
reset_password_token character varying,
reset_password_sent_at timestamp without time zone,
remember_created_at timestamp without time zone,
name character varying NOT NULL,
created_at timestamp without time zone NOT NULL,
updated_at timestamp without time zone NOT NULL,
description text,
CONSTRAINT email_length_check CHECK ((length((email)::text) > 0)) NO INHERIT,
CONSTRAINT name_length_check CHECK ((length((name)::text) > 0)) NO INHERIT
);
Rspec输出:
Randomized with seed 21829
F.F..
Failures:
1) User database checks empty email should raise ActiveRecord::StatementInvalid
Failure/Error: it { expect {user.save validate: false}.to raise_error ActiveRecord::StatementInvalid }
expected ActiveRecord::StatementInvalid but nothing was raised
# ./spec/models/user_spec.rb:28:in `block (4 levels) in <top (required)>'
2) User database checks empty name should raise ActiveRecord::StatementInvalid
Failure/Error: it { expect {user.save validate: false}.to raise_error ActiveRecord::StatementInvalid }
expected ActiveRecord::StatementInvalid but nothing was raised
# ./spec/models/user_spec.rb:34:in `block (4 levels) in <top (required)>'
Finished in 0.41576 seconds (files took 14.93 seconds to load)
5 examples, 2 failures
Failed examples:
rspec ./spec/models/user_spec.rb:28 # User database checks empty email should raise ActiveRecord::StatementInvalid
rspec ./spec/models/user_spec.rb:34 # User database checks empty name should raise ActiveRecord::StatementInvalid
Randomized with seed 21829
Rails控制台输出:
Running via Spring preloader in process 11864
Loading development environment (Rails 5.0.2)
[1] pry(main)> user = FactoryGirl.build :user, email: ''
=> #<User id: nil, email: "", name: "Test", created_at: "2017-04-09 00:19:37", updated_at: "2017-04-09 00:19:42", description: "Test description">
[2] pry(main)> user.save validate: false
(0.2ms) BEGIN
SQL (1.9ms) INSERT INTO "users" ("encrypted_password", "name", "created_at", "updated_at", "description") VALUES ($1, $2, $3, $4, $5) RETURNING "id" [["encrypted_password", "$2a$11$UCKPTyuQyfgyWibv3mlv4OFavF2nLtGwFhHvYJMmCepwevJhSja2u"], ["name", "Test"], ["created_at", 2017-04-09 00:19:37 UTC], ["updated_at", 2017-04-09 00:19:42 UTC], ["description", "Test description"]]
(0.2ms) ROLLBACK
ActiveRecord::StatementInvalid: PG::CheckViolation: ERROR: new row for relation "users" violates check constraint "email_length_check"
DETAIL: Failing row contains (9, , $2a$11$UCKPTyuQyfgyWibv3mlv4OFavF2nLtGwFhHvYJMmCepwevJhSja2u, null, null, null, Test, 2017-04-09 00:19:37.826153, 2017-04-09 00:19:42.826772, Test description).
: INSERT INTO "users" ("encrypted_password", "name", "created_at", "updated_at", "description") VALUES ($1, $2, $3, $4, $5) RETURNING "id"
from /Users/edgarlepe/.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems/activerecord-5.0.2/lib/active_record/connection_adapters/postgresql_adapter.rb:598:in `async_exec'
[3] pry(main)> user = FactoryGirl.build :user, name: ''
=> #<User id: nil, email: "test@example.com", name: "", created_at: "2017-04-09 00:20:21", updated_at: "2017-04-09 00:20:26", description: "Test description">
[4] pry(main)> user.save validate: false
(0.2ms) BEGIN
SQL (1.9ms) INSERT INTO "users" ("email", "encrypted_password", "name", "created_at", "updated_at", "description") VALUES ($1, $2, $3, $4, $5, $6) RETURNING "id" [["email", "test@example.com"], ["encrypted_password", "$2a$11$gmMGIjSKycqLmOybtxuWAee.OMHdyktzM2ZeR3ZawHEGkYk1SlMki"], ["name", ""], ["created_at", 2017-04-09 00:20:21 UTC], ["updated_at", 2017-04-09 00:20:26 UTC], ["description", "Test description"]]
(0.2ms) ROLLBACK
ActiveRecord::StatementInvalid: PG::CheckViolation: ERROR: new row for relation "users" violates check constraint "name_length_check"
DETAIL: Failing row contains (10, test@example.com, $2a$11$gmMGIjSKycqLmOybtxuWAee.OMHdyktzM2ZeR3ZawHEGkYk1SlMki, null, null, null, , 2017-04-09 00:20:21.010989, 2017-04-09 00:20:26.011515, Test description).
: INSERT INTO "users" ("email", "encrypted_password", "name", "created_at", "updated_at", "description") VALUES ($1, $2, $3, $4, $5, $6) RETURNING "id"
from /Users/edgarlepe/.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems/activerecord-5.0.2/lib/active_record/connection_adapters/postgresql_adapter.rb:598:in `async_exec'
用户模型:
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_many :articles
end