You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Ruby on Rails RSpec中能否用PG::Connection连接FactoryBot操作的数据库?

如何在RSpec测试中用PG::Connection连接FactoryBot操作的数据库?

我在Ruby on Rails的RSpec测试里尝试实例化PG::Connection,但遇到了FactoryBot插入的数据无法通过PG连接查询到的问题,相关代码和尝试的操作如下:

测试代码片段

before do
  FactoryBot.create(:user, first_name: first_name, last_name: last_name)
end

let(:conn) do
  PG::Connection.connect(
    'localhost', # host
    5432,        # port
    nil,         # options
    nil,         # tty
    'test',      # db name
    'postgres',  # username
    'password'   # password
  )
end

it 'works' do
  result = subject
  connection_config = User.connection_db_config
  puts connection_config
  require 'pry'
  binding.pry
end

已尝试的操作

  • 通过User.connection_db_config获取连接信息,结果为:
    => #<ActiveRecord::DatabaseConfigurations::UrlConfig:0x000000010536fac8
    @configuration_hash={:adapter=>"postgresql", :encoding=>"utf8", :pool=>100, :prepared_statements=>false, :database=>"test", :url=>nil},
    @env_name="test",
    @name="primary",
    @url=nil>
    
    • 无法判断连接参数是否有误
  • 在binding.pry断点中,User.last能返回FactoryBot创建的用户,但用conn.exec_params("select * from users")查询到0条数据
  • 测试被binding.pry暂停时,本地数据库看不到插入的User记录
  • database.yml配置如下,但断点中打印ENV['DATABASE_URL']为nil:
    test:
        <<: *default
        url: <%= ENV['DATABASE_URL'] %>
        database: test
    

解决方案

核心原因

RSpec默认开启事务测试,FactoryBot插入的数据处于未提交的事务中,不会对外部独立的PG::Connection实例可见;同时测试结束后事务会自动回滚,所以本地数据库也看不到记录。

具体解决步骤

  1. 复用ActiveRecord的数据库连接参数
    避免手动硬编码连接参数,直接从ActiveRecord的配置中提取,确保参数和Rails使用的完全一致:

    let(:conn) do
      db_config = User.connection_db_config.configuration_hash
      PG::Connection.connect(
        host: db_config[:host] || 'localhost',
        port: db_config[:port] || 5432,
        dbname: db_config[:database],
        user: db_config[:username] || 'postgres',
        password: db_config[:password]
      )
    end
    
  2. 让PG连接访问到事务内的数据
    有两种可行方式:

    • 方式一:获取ActiveRecord的底层PG连接(推荐)
      Rails的ActiveRecord连接本身就处于测试事务中,直接提取它的原生PG连接实例,就能直接访问FactoryBot插入的数据:
      let(:conn) do
        User.connection.raw_connection
      end
      
    • 方式二:关闭当前测试的事务(需手动清理数据)
      在测试组上关闭事务测试,FactoryBot插入的数据会直接提交到数据库,但需要手动清理避免测试污染:
      describe "Your test group" do
        self.use_transactional_fixtures = false
      
        after do
          User.destroy_all
        end
      
        # 你的测试代码...
      end
      

内容的提问来源于stack exchange,提问作者irregular

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 08:32:26