在 Rspec 中测试物化视图

Bet*_*rds 6 postgresql rspec ruby-on-rails materialized-views scenic

使用Scenic gem,我构建了一个由物化视图支持的 ActiveRecord 模型

class MatviewSales < ActiveRecord::Base
  self.table_name = 'matview_sales'
  self.primary_key = :id

  belongs_to :user
  belongs_to :account
  belongs_to :account_manager, class_name: User, foreign_key: 'manager_id'

  def self.refresh
    Scenic.database.refresh_materialized_view(table_name, concurrently: true)
  end
end
Run Code Online (Sandbox Code Playgroud)

我现在尝试在 RSpec 中测试这个模型,但无论我做什么,我都无法让 Postgres 用记录填充视图:

> FactoryGirl.create(:sale_item)
> MatviewSales.refresh
> MatviewSales.all
=> #<ActiveRecord::Relation []> 
Run Code Online (Sandbox Code Playgroud)

如何使用测试记录填充物化视图?

小智 8

刷新物化视图不会考虑任何尚未提交的事务。

当使用 rspecuse_transactional_fixturesDatabaseCleaner.strategy = :transaction这意味着,您的视图将不会看到任何先前的FactoryGirl.create记录。

我使用的解决方案是关闭使用物化视图的特定测试的事务。

# spec_helper.rb
RSpec.configure do |config|
  config.use_transactional_fixtures = false
  # ... other configurations
  config.around(:each) do |example|
    DatabaseCleaner.strategy = example.metadata.fetch(:clean_database_with, :transaction)
    DatabaseCleaner.start

    example.run

    DatabaseCleaner.clean
  end
end

# your test
describe MatviewSales, clean_database_with: :truncation do
  it 'works :)' do
    FactoryGirl.create(:sale_item)
    MatviewSales.refresh
    expect(MatviewSales.count).to eq 1
  end
end
Run Code Online (Sandbox Code Playgroud)

有关 use_transactional_fixtures 的文档