【问题标题】:RSpec testing an error is thrown, ActiveRecord connectionRSpec 测试抛出错误,ActiveRecord 连接
【发布时间】:2013-03-28 15:44:01
【问题描述】:

我在 Rails 应用程序中做了一件有趣的事情,连接到不同的数据库以读取信息,但不写入信息。为了便于建立这些连接,我编写了模型来处理表格。我有两个类似的课程,所以这里有一个可以说明问题:

# call.rb
class Call < ActiveRecord::Base
  # We don't want to change these values in the table, only read them
  attr_reader :uniqueid, :queue, :agent_id, :codes, :code_count

  def self.connect
    establish_connection "ihs"
    self.table_name = 'calls'
  end

  def self.disconnect
    self.connection.close
  end
end

我不希望此连接覆盖到 Rails 应用程序数据库的主连接,这只是暂时的。所以现在,我想测试这些连接是否在我调用这些方法时实际建立和关闭。目前我的想法是这样的:

# call_spec.rb
describe Call do

  [code omitted]

  describe "#connect" do
    # before { Call.disconnect }

    it "establishes a connection to IHS DB" do
      puts Call.count
      lambda { Call.count }.should raise_error(ActiveRecord::StatementInvalid)
      Call.connect
      lambda { Call.count }.should_not raise_error
    end
  end
end

我已经使用begin ... rescue Exception =&gt; e; puts e.class; end 测试了这段代码来验证抛出的异常类型,它确实是一个 ActiveRecord::StatementInvalid 异常,但是这个测试没有通过。我被抛出的错误如下:

Failure/Error: puts Call.count
  ActiveRecord::StatementInvalid:
    PG::Error: ERROR:  relation "calls" does not exist
      [rest omitted]

这是我期望得到的错误,我只是不知道如何调整测试以通过。有什么建议吗?

【问题讨论】:

  • 我注意到两件事,首先,在真正的异常之前对Call.count的调用只是为了调试目的?因为如果不是,它可能会引发异常,为什么不使用传统的expect{}.to raise_error 参见relishapp.com/rspec/rspec-expectations/v/2-6/docs/…
  • 哈哈哇。不敢相信它一直就在我面前。非常感谢!留下一个答案,我会为你接受!

标签: ruby-on-rails database activerecord rspec


【解决方案1】:

来电

puts Call.count

在实际异常之前,在 rspec '捕获'它之前引发错误。

【讨论】:

  • 为了回答评论中的第二个问题,我发现 lambda 语法更接近于我的其他测试的格式(使用 shouldshould_not 而不是 tonot_to )。只是似乎读起来好一点。
【解决方案2】:

我想知道为什么明确连接和断开连接很重要?在一个我想连接到辅助数据库进行读取的应用程序中,我让所有的 activerecord 类都继承自一个负责连接的基类,如下所示:

class IhsActiveRecord < ActiveRecord::Base
  self.abstract_class = true
  establish_connection "#{Rails.env}_ihs"
end

这样您就不会不断地重新连接和断开连接,并且可以将连接逻辑保存在一个地方。实际的连接信息仍然可以放在您的 database.yml 文件中。上面,我每个环境都有一个单独的,你可以调整,只要它匹配你的database.yml。

我还建议在您的规范中使用 expect {} 而不是 lambda。

【讨论】:

  • 感谢您的回复!我相信我以前尝试过以这种方式建立连接,但它似乎弄乱了我的基本连接(到 Rails 应用程序正在使用的数据库),所以我尝试了一种不同的方法。此外,这个数据库只是我需要从中提取信息的数据库,而不是以任何方式更新的,所以我想确保它只有在绝对必要时才能访问。这有意义吗,还是我还是有点漏掉了标记?
  • 至少有一些数据库在连接时会对性能造成很大影响,因此我会尽量避免这样做。您可能会在此处查看有关仅创建模型的 cmets:apidock.com/rails/ActiveRecord/Base/readonly%3F 并且可能还定义您自己的空“删除”和“销毁”方法,或引发异常的版本。
  • 非常感谢您的指点!我刚刚完成了这些方法的实现,现在对整个模型感到更加安全。
猜你喜欢
  • 1970-01-01
  • 2012-12-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多