如何模拟存储过程



考虑以下stored procedure:

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

为什么会发生这种情况?我在嘲笑你吗

数据库是postgres 9.1

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

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

另一个SO帖子表明您可以避免全局禁用事务,并在每个测试的基础上关闭它们,我自己也没有尝试过。

相关内容

  • 没有找到相关文章

最新更新