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

时间:2015-01-20 13:21:30

标签: ruby-on-rails unit-testing fixtures

有没有办法在运行测试时按特定顺序加载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按字母顺序加载夹具,Memberships会在Users之前加载,并且会出现错误,说明关系不存在(正确地说是这样)。

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

在运行测试时,有没有办法在加载Users之前加载GroupsMemberships灯具?

3 个答案:

答案 0 :(得分:38)

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

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

以下是解决问题的方法:

  1. 使用您的默认超级用户登录Postgresql(我的是&#34; postgres&#34;)
  2. 执行以下命令:

    ALTER ROLE yourtestdbuser WITH SUPERUSER;
    
  3. 享受正常工作的装置。

  4. 当一个人使用Postgresql和没有超级用户角色的用户运行测试数据库时,下一个版本的Rails会发出警告(我认为非常需要)。我在a Rails GitHub issue suggesting the warning上找到了这个。

答案 1 :(得分:9)

向您的“测试”帐户授予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

时进行

答案 2 :(得分:0)

至少对于Rails 5,可以将<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet" /> <div id="grid5" class="w3-row-padding w3-padding-64 w3-container"> <div class="w3-content"> <div> <h1 class="text-center" data-aos="fade-up">Next Step</h1> <br> <br> <br> <div class="container"> <div class="row flex-row"> <div class="col"> <div class="w3-third w3-center"> <div data-aos="fade-right" data-aos-offset="300" data-aos-easing="ease-in-sine"> <img src="images/snake.jpg" class="w3-hover-sepia" style="box-shadow: 3px 3px 5px black;width: 18em; height: 18em;" alt="Person"> </div> </div> </div> <div class="col"> <div class="w3-third w3-center"> <div data-aos="fade-left" data-aos-offset="300" data-aos-easing="ease-in-sine"> <img src="images/snake.jpg" class="w3-hover-sepia" style="box-shadow: 3px 3px 5px black;width: 18em; height: 18em;" alt="Person"> </div> </div> </div> </div> <br> <div class="row flex-row"> <div class="col"> <div class="w3-third w3-center"> <div data-aos="fade-right" data-aos-offset="300" data-aos-easing="ease-in-sine"> <img src="images/snake.jpg" class="w3-hover-sepia" style="box-shadow: 3px 3px 5px black;width: 18em; height: 18em;" alt="Person"> </div> </div> </div> <div class="col"> <div class="w3-third w3-center"> <div data-aos="fade-left" data-aos-offset="300" data-aos-easing="ease-in-sine"> <img src="images/snake.jpg" class="w3-hover-sepia" style="box-shadow: 3px 3px 5px black;width: 18em; height: 18em;" alt="Person"> </div> </div> </div> </div> </div> </div> </div> </div>替换为fixtures :all。它将按该顺序插入它们。但不要忘记任何夹具文件:-)