Rails中如何用RSpec测试PostgreSQL类型的Enum字段?
在Rails中测试PostgreSQL原生Enum字段的问题
我有一个crops表,其中包含PostgreSQL原生类型的enum字段crop_type,对应的迁移代码、模型代码如下。使用RSpec的define_enum_for方法测试时出现错误,请问该如何测试这种非整数类型的Enum字段?
迁移代码
def up create_table :crops do |t| t.string :name execute <<-SQL CREATE TYPE crop_type AS ENUM ('fruit', 'vegetable', 'other_crop'); SQL t.column :crop_type, :crop_type t.timestamps end end
模型代码
class Crop < ApplicationRecord enum crop_type: { fruit: 'fruit', vegetable: 'vegetable', other_crop: 'other_crop' } end
测试代码
it { should define_enum_for(:crop_type).with_values({ fruit: 'fruit', vegetable: 'vegetable', other_crop: 'other_crop' }) }
错误信息
Expected Crop to define :crop_type as an enum backed by an integer,
mapping ‹"fruit"› to ‹"fruit"›, ‹"vegetable"› to ‹"vegetable"›, and
‹"other_crop"› to ‹"other_crop"›. However, :crop_type is an enum column.
解决方案
RSpec的define_enum_for匹配器默认是为Rails内置的整数类型枚举设计的,而PostgreSQL原生Enum字段在Rails中直接映射为字符串值的枚举,因此会触发上述错误。你需要放弃使用define_enum_for,转而手动测试枚举的核心行为:
1. 验证枚举键值对的正确性
it 'defines correct crop_type enum mappings' do expect(Crop.crop_types).to eq( fruit: 'fruit', vegetable: 'vegetable', other_crop: 'other_crop' ) end
2. 测试实例的枚举方法
验证实例是否拥有枚举对应的赋值和查询方法:
describe '#crop_type enum methods' do let(:crop) { Crop.new } it 'supports setting via enum key methods' do crop.fruit! expect(crop.fruit?).to be true expect(crop.crop_type).to eq('fruit') end it 'supports direct value assignment' do crop.crop_type = 'vegetable' expect(crop.vegetable?).to be true end end
3. 测试枚举查询作用域
验证基于枚举的类级查询方法是否正常工作:
describe 'crop_type scopes' do before do @fruit_crop = Crop.create!(name: 'Apple', crop_type: 'fruit') @vegetable_crop = Crop.create!(name: 'Carrot', crop_type: 'vegetable') @other_crop = Crop.create!(name: 'Mushroom', crop_type: 'other_crop') end it 'returns correct records for each scope' do expect(Crop.fruit).to include(@fruit_crop) expect(Crop.vegetable).to include(@vegetable_crop) expect(Crop.other_crop).to include(@other_crop) end end
内容的提问来源于stack exchange,提问作者mrateb
相关产品推荐
相关产品推荐

