测试时按特定顺序装载导轨夹具

有没有办法在运行测试时按特定顺序加载Rails灯具? 例如,参加以下课程……

class User < ActiveRecord::Base has_many :memberships has_many :groups, through: :memberships end class Group < ActiveRecord::Base has_many :memberships has_many :users, through: :memberships end class Membership < ActiveRecord::Base belongs_to :user belongs_to :group end 

Memberships具有数据库级外键约束,要求UsersGroups在创建之前存在。 但是,由于Rails按字母顺序加载fixture,因此MembershipsUsers之前加载Memberships ,并且会发生错误,指出关系不存在(正确地说是这样)。

 ActiveRecord::InvalidForeignKey: PG::ForeignKeyViolation: ERROR: insert or update on table "memberships" violates foreign key constraint 

有没有办法在运行测试时加载Memberships之前加载UsersGroups夹具?

您的问题不是Rails运行测试的顺序。 我遇到了和你一样的问题,经过几个小时的调试后发现,ActiveRecord实际上在插入夹具记录时会禁用参照完整性,以防止Postgresql出现这些类型的错误。

问题在于,您的测试数据库用户必须拥有ActiveRecord测试数据库的超级用户权限才能成功禁用fixture的参照完整性。

以下是解决问题的方法:

  1. 使用默认超级用户登录Postgresql(我的是“postgres”)
  2. 执行以下命令:

     ALTER ROLE yourtestdbuser WITH SUPERUSER; 
  3. 享受你正常工作的灯具。

当一个人使用Postgresql运行测试数据库和没有超级用户角色的用户时,Rails的下一个版本将发出警告(我认为非常需要)。 我在一个Rails GitHub问题上发现了这个警告 。

向您的“测试”帐户授予PostgreSQL超级用户权限允许Rails以其想要的方式工作。 在不希望/不可行的情况下……

是的,如果不支持,可以控制加载和删除灯具的顺序(两者都很重要)。

test/test_helper.rb

 class ActiveRecord::FixtureSet class << self alias :orig_create_fixtures :create_fixtures end def self.create_fixtures f_dir, fs_names, *args # Delete all fixtures that have foreign keys, in an order that # doesn't break referential integrity. Membership.delete_all reset_cache # If we're adding any {user, group} fixtures, add them [a] in that # order, [b] before adding any other fixtures which might have # references to them. fs_names = %w(users groups) & fs_names | fs_names orig_create_fixtures f_dir, fs_names, *args end end 

使用Rails 4.2.3进行测试,并且仅在使用fixtures :all