【问题标题】:How do you test Postgres's LISTEN / NOTIFY with ActiveRecord?你如何使用 ActiveRecord 测试 Postgres 的 LISTEN / NOTIFY?
【发布时间】:2014-11-07 03:42:56
【问题描述】:

假设我正在使用 pg gem 和 RSpec,我应该采取什么方法来正确测试我的 LISTENNOTIFY 语句是否有效? pg 的wait_for_notify 阻塞,所以我似乎无法“通知,然后收听”或“收听,然后通知”。我忽略了什么吗?

例如:

it "notifies" do
  conn = ActiveRecord::Base.connection

  it_ran = false

  conn.execute "LISTEN my_channel"
  conn.execute "NOTIFY my_channel, 'hello'"
  conn.wait_for_notify(1) do |channel, pid, payload|
    it_ran = true
  end

  expect(it_ran).to eq true
end

编辑:

这适用于控制器,甚至是 rails 控制台,但由于某种原因,它在 RSpec 测试中不起作用。奇怪的是,直接使用 pg gem 确实有效。为什么 ActiveRecord 在这种情况下可能不起作用?

【问题讨论】:

    标签: ruby postgresql activerecord rspec


    【解决方案1】:

    wait_for_notify() 仅在需要时阻止。也就是说,当通知队列中还没有任何内容时。

    在您的代码中,基于您的第一个NOTIFY,队列中已经有一个通知,因此wait_for_notify() 将立即返回并设置it_ran。

    如果我去掉 ActiveRecord 的东西并直接使用 pg,这正是发生的事情。

    【讨论】:

    • 嗯,你是对的,直接使用 pg gem 时确实有效。很高兴看到它实际上正在排队。你知道为什么它不能与 ActiveRecord 一起工作吗?谢谢你的回答。
    • 我对 ActiveRecord 知之甚少。你的代码 sn-p 根本不适合我(13: syntax error, unexpected end-of-input, expecting keyword_end),我不知道如何修复它,所以我把它撕掉了。我会在 postgresql 端启动日志记录,看看命令是否到达服务器;但那是因为我的经验是使用 postgresql,而不是 ruby​​。
    • 那是我的错,我在 RSpec 测试中留下了一个额外的do。还是谢谢。
    【解决方案2】:

    原来问题出在 DatabaseCleaner 上。有了这个,我尝试使用其他策略而不是事务,但没有任何效果;似乎让LISTEN / NOTIFY 在 ActiveRecord 连接上工作的唯一方法是在该测试中禁用它。

    以下是我最终为特定测试禁用 DatabaseCleaner 的方式。在我的支持配置文件中:

    RSpec.configure do |config|
      # BEFORE:
      # config.before(:each) do
      #   DatabaseCleaner.strategy = :transaction
      # end
    
      # AFTER:
      config.before(:each) do |test|
        unless test.metadata[:no_database_cleaner]
          DatabaseCleaner.strategy = :transaction
        end
      end
    
    end
    

    在我的规范文件中:

    RSpec.describe "Postgres LISTEN / NOTIFY" do
      it "notifies", :no_database_cleaner => true do
        # [clipped]
      end
    end
    

    现在每当我需要测试LISTEN / NOTIFY 时,我都会将:no_database_cleaner => true 添加到it 块中。

    【讨论】:

      猜你喜欢
      • 2013-04-30
      • 2018-01-07
      • 2015-12-31
      • 2014-02-04
      • 2018-07-18
      • 2016-11-26
      • 2023-04-01
      • 2017-03-08
      • 2014-03-05
      相关资源
      最近更新 更多