【问题标题】:How to get Rspec to use the same DB connection for reader and writer DB in rails 6?如何让 Rspec 在 Rails 6 中为读取器和写入器数据库使用相同的数据库连接?
【发布时间】:2023-01-31 03:37:08
【问题描述】:

对于上下文,出现这个问题是因为我们正在从 Rails 5 迁移到 Rails 6,并通过新的复制功能引入读取器/写入器数据库连接。

我们的具体问题是请求规范,着眼于使用交易固定装置。当我们单独运行我们的请求规范文件时,它们通过了。当作为多文件传递的一部分运行时(例如在 circle CI 上使用的完整 bundle exec parallel_rspec 传递)它们会失败。如果我们关闭事务固定装置,测试运行的时间太长,但会通过。

使用byebug,我们已经确定问题是我们的测试数据已写入/可由编写器数据库连接访问,但该路由正在尝试使用读取器数据库连接来读取它。 I. E. ActiveRecord::Base.connected_to(role: :reading) { puts Foo.count } 为 0,而连接到 writing 角色的相同代码为非零。

那里的问题似乎相当明显:因为我们使用的是事务测试/固定装置,所以代码永远不会提交给数据库。它仅在建立它的连接上可用。请求规范正在从调用的“正确”数据库中读取(GET 请求应使用读取器数据库),但在产生错误的测试用例中。

看起来这是一个相当明显的用例,无论是 Rails 还是 rspec应该有工具可以处理,只是好像找不到相关的文档。

【问题讨论】:

    标签: ruby-on-rails rspec


    【解决方案1】:

    您需要告诉测试环境它应该为两者使用一个连接。有多种方法可以做到这一点:

    1. 您可以将您的test 环境配置为完全不使用副本。请参阅 Setting up your application 了解使用副本和不使用副本的示例,然后在 database.yml 中复制非副本版本仅用于测试环境。
    2. 您可以在您的规范中使用connected_to,这样这些测试就会强制使用您希望它们使用的特定连接。一种方法是使用around hooks
      describe "around filter" do
        around(:each) do |example|
          puts "around each before"
          ActiveRecord::Base.connected_to(role: :writing) { example.run }
          puts "around each after"
        end
      
        it "gets run in order" do
          puts "in the example"
        end
      end
      
      1. 你可以在rails_helper 中修改你的 ActiveRecord 配置,这样它就不会使用副本(但我真的建议 #1 超过这个选项)

    【讨论】:

      猜你喜欢
      • 2017-10-19
      • 1970-01-01
      • 1970-01-01
      • 2011-06-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-25
      • 2012-06-22
      相关资源
      最近更新 更多