ruby - RSpec - 如何模拟存储过程

标签 ruby postgresql rspec mocking

考虑以下存储过程:

CREATE OR REPLACE FUNCTION get_supported_locales()
RETURNS TABLE(
  code character varying(10)
) AS
...

下面是调用它的方法:

def self.supported_locales
  query = "SELECT code FROM get_supported_locales();"
  res = ActiveRecord::Base.connection.execute(query)
  res.values.flatten
end

我正在尝试为此方法编写测试,但在模拟时遇到了一些问题:

it "should list an intersection of locales available on the app and on last fm" do
  res = mock(PG::Result)
  res.should_receive(:values).and_return(['en', 'pt'])
  ActiveRecord::Base.connection.stub(:execute).and_return(res)

  Language.supported_locales.should =~ ['pt', 'en']
end

此测试成功但在此之后运行的任何测试都会提供以下消息:

WARNING:  there is already a transaction in progress

为什么会这样?我在 mock 吗

数据库是postgres 9.1。

最佳答案

您的测试正在使用数据库级事务运行。当测试完成时,事务被回滚,这样测试中所做的任何更改都不会实际保存到数据库中。在您的情况下,这种回滚不会发生,因为您已经删除了 ActiveRecord 连接上的执行方法。

您可以全局禁用事务并切换到使用 DatabaseCleaner为各种测试启用/禁用事务。然后您可以设置默认情况下通过 DatabaseCleaner 使用事务,这样您现有的测试就不会改变,然后在这个测试中选择禁用事务以支持其他一些策略(例如 null 策略,因为没有清理是完成此测试)。

This other SO post表示您可以避免全局禁用事务并在每次测试时也将其关闭,不过我自己还没有尝试过。

关于ruby - RSpec - 如何模拟存储过程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14023105/

相关文章:

ruby-on-rails - 模型中的一个或多个参数使用 Ruby on Rails 查找条件

arrays - 数组格式的 Ruby PG gem 选择字段

sqlite - SQLAlchemy、反射、不同的后端和表/列不区分大小写

ruby-on-rails - 使用 rspec 检查错误的枚举

rspec - 如何配置 RSpec 来加载猴子补丁类

ruby-on-rails - 如何将 CURL 请求转换为 Ruby Gem HTTPClient

python - 在 Ruby/Python 中可视化 x、y、z 坐标?

ruby-on-rails - Rails/Rspec : Testing delayed_job mails

Ruby #select,但只选择某个数字

ruby-on-rails - STI、MTI 或 CTI,目前建议的 Rails 4 解决方案是什么?