在运行RSpec测试时,从Ruby调用shell命令会挂起

时间:2017-05-08 20:31:26

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

以下方案产生预期结果:

    来自zsh的
  1. ,执行:

    /usr/local/bin/pg_dump mydatabase  #=> a bunch of sql output
    
  2. 从irb或rails控制台
  3. 执行:

    `/usr/local/bin/pg_dump my_database` #=> a bunch of sql output
    
  4. 从方法中调用相同的shell命令:

    class AppDb
      def contents
        `/usr/local/bin/pg_dump my_database`
      end
    end
    
    # from rails console:
    AppDb.new.contents #=> a bunch of sql stuff
    
  5. 但是,当我从Rspec测试同一个AppDb类时,shell命令无限期地挂起断言:

    expect(AppDb.new.contents).to match "PostgreSQL database dump complete"
    

    你知道为什么会这样吗?

1 个答案:

答案 0 :(得分:1)

悬念是由于:

  1. spec_helper.rb中的rspec配置

    config.use_transactional_fixtures = true

    这会启动一个postgresql BEGIN块,它会启动对表的锁定

  2. 结合使用pg_dump,由于数据库锁定而无法执行。它会挂起(永久或指定的超时),等待锁被删除。

  3. 所以解决方法就是将use_transactional_fixtures设置为false。当然,这会在规范的最后给数据库留下测试数据,这必须以另一种方式处理。可以使用DatabaseCleaner,但不能使用事务策略,因为这会遇到同样的问题。