【问题标题】:Using 2 separate databases in Rspec for testing libary在 Rspec 中使用 2 个独立的数据库来测试库
【发布时间】:2019-01-29 14:28:13
【问题描述】:

我的 Rails5 应用程序有很多规格,这些都是针对 postgres 运行的,因为我的生产/开发也是 postgres。

我开发了一些位于 app/lib 中的库,并且肯定需要规范 这些规范需要一些还需要数据库的缩小模型。由于我不想仅仅为了规范而在我的 postgres 中维护迁移,我认为在 sqlite3 上运行这些迁移是很好的,因为它的通用模型。

所以经过大量的来回后,我被卡住了。

我有典型的spec_helper.rb 没什么特别的,并决定去

sqlite_spec_helper.rb:

require './spec/support/reference_app/app'

support/reference_app/app

require 'active_record/railtie'
require 'action_controller/railtie'
require 'responders'
require './spec/support/reference_app/configure_active_record'

class Application < Rails::Application
  config.eager_load = false
  config.secret_key_base = 'supersecret'
end

class ApplicationController < ::ActionController::API
  include Rails.application.routes.url_helpers

  respond_to :json
end

Application.initialize!

require 'rspec/rails'

RSpec.configure do |config|
  config.infer_base_class_for_anonymous_controllers = true
end

spec/support/reference_app/configure_active_record

ENV['RACK_ENV'] = 'test'

ActiveRecord::Base.establish_connection(
  adapter: 'sqlite3',
  database: ':memory:'
)

ActiveRecord::Schema.define do
  self.verbose = false

  create_table :generic_table do |t|
    t.string :name
    t.string :type
  end
end

所以我通常的规范在顶部有require 'spec_helper,而库规范有require 'sqlite_spec_helper'。所以我的想法是库规范然后使用之前加载的 sqlite 连接。

当我运行应该使用我遇到的 sqlite db 的测试时

ActiveRecord::StatementInvalid:
       PG::UndefinedTable ...

这意味着它仍然适用于 pg 连接。有什么有用的提示或信息吗?

【问题讨论】:

  • 您的.rspec 文件中有什么内容?这是一种配置规范运行之前发生的事情的方法。
  • 也许在你做 Application.initialize! 之后调用 require './spec/support/reference_app/configure_active_record' 也许它正在用 config/database.yml 信息覆盖你的 ActiveRecord 配置
  • @ DickieBoy.rspec 文件只需要 --color 选项以避免将 spec_helper 加载到每个测试中。 @Tyrone Wilson 好提示。这至少让我更近了一步。如果我运行我的 2 个规范,其中一个是库和一个 postgres 堆栈,它们都可以自己正常工作。但是当我运行整个 rspec 套件时,它会失败,因为它似乎都是针对 sqlite db 运行的。他们显然失败了。所以我猜 rspec 急切地加载所有内容,最终其中一个 dbs 是最后一个定义并覆盖另一个。
  • @daniel,除了想知道为什么需要这样做之外,我个人只是通过克隆 environment/test.rb 来创建另一个环境并使其成为 libtest 或其他东西。但是,如果不了解完整的背景,就很难评论最适合您的前进方式。我确实怀疑不需要运行单独的测试。如果您希望能够运行其中一个,那么只需标记它们并使用过滤器运行。
  • 听起来你应该在这种情况下创建一个 gem。听起来你的模特“太胖了”。即您应该仅将模型用于与数据库相关的东西,然后组合其他可以单独测试的功能。 medium.com/@tyrone.wilson/…这是我对这个主题的看法,它通常对我很有帮助。

标签: ruby-on-rails postgresql sqlite rspec ruby-on-rails-5


【解决方案1】:

找到了我最初的问题的解决方案。尽管请记住,更好的方法是将库提取到 gem 并按照@Tyrone 的建议在其中相应地指定它。把这个放到spec_helper

RSpec.configure do |config|
  config.before(:each, :library) do |example|
    ActiveRecord::Base.establish_connection(
      adapter: 'sqlite3',
      database: ':memory:'
    )

    ActiveRecord::Schema.define do
      self.verbose = false

      create_table :abstract_dummies do |t|
        t.string  :type
        t.text   :meta_data
      end

      create_table :generic_table do |t|
        t.string :name
        t.string :type
      end

      create_table :users do |t|
      end
    end
  end

  config.after(:each, :library) do |example|
    ActiveRecord::Base.establish_connection(:test)
  end
end

:library 以你的例子为例

describe LibraryClass::Foo::Bar, :library do
end

这将为每个示例使用 sqlite3 连接并将其设置回您的 database.yml 中的默认 :test 这样它不会影响现有的 rails 堆栈规范。

【讨论】:

    猜你喜欢
    • 2021-07-19
    • 1970-01-01
    • 1970-01-01
    • 2022-01-23
    • 1970-01-01
    • 1970-01-01
    • 2011-03-09
    • 1970-01-01
    • 2012-09-18
    相关资源
    最近更新 更多